1203 lines
39 KiB
C++
1203 lines
39 KiB
C++
#ifndef IScene_h__
|
|
#define IScene_h__
|
|
|
|
#define _CRTDBG_MAP_ALLOC
|
|
#include <stdlib.h>
|
|
#include <crtdbg.h>
|
|
#include "LifeDebug.h"
|
|
|
|
#include "IGraphicsNode.h"
|
|
#include "LString.h"
|
|
#include <map>
|
|
#include <vector>
|
|
//#include "IMesh.h"
|
|
#include "render/IConstantBuffer.h"
|
|
#include "math/LifeMath.h"
|
|
#include "Globals.h"
|
|
#include "camera/Camera.h"
|
|
#include "Light.h"
|
|
#include "RenderQueue.h"
|
|
#include "ResourceManager.h"
|
|
#include "Rectangle2D.h"
|
|
#include "ShadowMapManager.h"
|
|
#include "Types.h"
|
|
#include "RenderPass.h"
|
|
#include "render/PostEffect.h"
|
|
#include "render/PosteffectManager.h"
|
|
#include "render/PostHDR.h"
|
|
#include "render/PostDOF.h"
|
|
#include "render/PostSSAO.h"
|
|
#include "Terrain.h"
|
|
#include "Sky.h"
|
|
#include "vegetation/PlantManager.h"
|
|
#include "passPSSM.h"
|
|
#include "IObject.h"
|
|
#include "IObjectMesh.h"
|
|
#include "Timer.h"
|
|
#include "queries/IFrustumQuery.h"
|
|
#include "constants.h"
|
|
#include "renderpath/RenderPathOmniShadow.h"
|
|
#include "renderpath/RenderPathSpotShadow.h"
|
|
#include <IRenderOutput.h>
|
|
|
|
namespace LifeGraphics
|
|
{
|
|
class TransformGraphRootNode : public IGraphicsNode
|
|
{
|
|
public:
|
|
TransformGraphRootNode(){}
|
|
~TransformGraphRootNode(){}
|
|
NodeType getType()
|
|
{
|
|
return NT_SCENE_ROOT;
|
|
}
|
|
void update(float dt)
|
|
{
|
|
}
|
|
};
|
|
|
|
struct PER_SCENE_CONSTANTS
|
|
{
|
|
float fTime;
|
|
LifeMath::float3 ambient;
|
|
LifeMath::float2 screenSize;
|
|
LifeMath::float2 ssaoSize;
|
|
};
|
|
|
|
struct CullPattern
|
|
{
|
|
bool cullFrustum;
|
|
bool cullMaterial;
|
|
uint32 castShadows;
|
|
};
|
|
|
|
struct LPP_QUAD_VERT
|
|
{
|
|
LifeMath::float4 position;
|
|
LifeMath::float3 texIndex;
|
|
};
|
|
|
|
class IScene
|
|
{
|
|
public:
|
|
Camera* mainCam;
|
|
int INDEX;
|
|
void SetMainCamera(Camera* cam)
|
|
{
|
|
mainCam = cam;
|
|
}
|
|
|
|
void ResizeOutput(int width, int height)
|
|
{
|
|
outputWidth = width;
|
|
outputHeight = height;
|
|
|
|
delete sceneG_normal;
|
|
delete sceneG_color;
|
|
delete sceneG_depth;
|
|
delete sceneLbuf;
|
|
|
|
//sceneRt = CG::me()->GetRenderer()->CreateRenderTarget(width, height, FORMAT_R16G16B16A16_FLOAT);
|
|
|
|
sceneG_normal = CG::me()->GetRenderer()->CreateRenderTarget(width, height, FORMAT_R8G8B8A8_UNORM);
|
|
sceneG_color = CG::me()->GetRenderer()->CreateRenderTarget(width, height, FORMAT_R8G8B8A8_UNORM);
|
|
sceneG_depth = CG::me()->GetRenderer()->CreateRenderTarget(width, height, FORMAT_R16G16_FLOAT);
|
|
|
|
sceneLbuf = CG::me()->GetRenderer()->CreateRenderTarget(width, height, FORMAT_R16G16B16A16_FLOAT);
|
|
//sceneDt = CG::me()->GetRenderer()->CreateDepthTarget(width, height, FORMAT_D24_UNORM_S8_UINT);
|
|
|
|
mainCam->setAspect(float(width) / float(height));
|
|
}
|
|
|
|
IScene(int width, int height)
|
|
:sun(0), sceneTime(0.0f), sky(0), terra(0), plantManager(0)
|
|
{
|
|
pssm = new passPSSM();
|
|
//pssm->Init();
|
|
postManager = new PostEffectManager();
|
|
|
|
//sky = new Sky();
|
|
//sky->Build();
|
|
//terra = new Terrain(TD_X512,64,100);
|
|
terra = NULL;
|
|
|
|
//plantManager = new PlantManager();
|
|
//plantManager->Init(terra);
|
|
|
|
mainCam = new Camera();
|
|
INDEX = 0;
|
|
outputWidth = width;
|
|
outputHeight = height;
|
|
|
|
SceneDescriptor desc;
|
|
desc.width = width;
|
|
desc.height = height;
|
|
postManager->Init(desc);
|
|
|
|
/*dof = new PostDOF();
|
|
dof->Init(desc);
|
|
postManager->Add(dof);*/
|
|
|
|
hdr = new PostHDR();
|
|
hdr->Init(desc);
|
|
postManager->Add(hdr);
|
|
|
|
angle = 0;
|
|
cbGlobal = CG::me()->GetRenderer()->CreateConstantBuffer(sizeof(PER_SCENE_CONSTANTS));
|
|
|
|
cbPerCamera = CG::me()->GetRenderer()->CreateConstantBuffer(sizeof(PER_CAMERA_CONSTANTS));
|
|
cbPerCameraLight = CG::me()->GetRenderer()->CreateConstantBuffer(sizeof(PER_CAMERA_CONSTANTS));
|
|
cbPointLights = CG::me()->GetRenderer()->CreateConstantBuffer(sizeof(POINT_LIGHT_DATA));
|
|
cbSpotLights = CG::me()->GetRenderer()->CreateConstantBuffer(sizeof(SPOT_LIGHT_DATA));
|
|
cbDirectionalLights = CG::me()->GetRenderer()->CreateConstantBuffer(sizeof(DIR_LIGHT_DATA));
|
|
cbSkinData = CG::me()->GetRenderer()->CreateConstantBuffer(PerObjectSkinningVSDataSize);
|
|
|
|
cbStencilSphere = CG::me()->GetRenderer()->CreateConstantBuffer(sizeof(LifeMath::float4));
|
|
|
|
cbShadowInfo = CG::me()->GetRenderer()->CreateConstantBuffer(sizeof(SHADOW_DATA));
|
|
|
|
lppBlend = CG::me()->GetRenderer()->CreateBlendState(true, false, BLEND_OP_ADD, BLEND_ONE, BLEND_ONE, 1 | 2 | 4 | 8);
|
|
gppBlend = CG::me()->GetRenderer()->CreateBlendState(false, false, BLEND_OP_ADD, BLEND_ONE, BLEND_ONE, 1 | 2 | 4 | 8);
|
|
|
|
//disable color write
|
|
bsNoWrite = CG::me()->GetRenderer()->CreateBlendState(false, false, BLEND_OP_ADD, BLEND_ONE, BLEND_ONE, 0);
|
|
|
|
appBlend = CG::me()->GetRenderer()->CreateBlendState(true, false, BLEND_OP_ADD, BLEND_SRC_ALPHA, BLEND_INV_SRC_ALPHA, 1 | 2 | 4 | 8);
|
|
|
|
gppDepthState = CG::me()->GetRenderer()->CreateDSState(true, true, COMPARISON_LESS);
|
|
|
|
lppDepthState = CG::me()->GetRenderer()->CreateDSState(false, false, COMPARISON_NEVER);
|
|
fppDepthState = CG::me()->GetRenderer()->CreateDSState(true, false, COMPARISON_EQUAL);
|
|
//always replace
|
|
//equal keep
|
|
|
|
dsLitStencilOne = CG::me()->GetRenderer()->CreateDSState(true, false, COMPARISON_LESS_EQUAL, true, 0xff, COMPARISON_ALWAYS,
|
|
STENCIL_OP_KEEP, STENCIL_OP_INCR, STENCIL_OP_INCR, STENCIL_OP_KEEP);
|
|
|
|
dsLitStencilTwo = CG::me()->GetRenderer()->CreateDSState(true, false, COMPARISON_GREATER_EQUAL, true, 0xff, COMPARISON_EQUAL,
|
|
STENCIL_OP_DECR, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP);
|
|
|
|
dsLitStencilLast = CG::me()->GetRenderer()->CreateDSState(false, false, COMPARISON_GREATER_EQUAL, true, 0xff, COMPARISON_EQUAL, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_DECR_SAT);
|
|
|
|
dsLitStencilLast2 = CG::me()->GetRenderer()->CreateDSState(false, false, COMPARISON_GREATER_EQUAL, true, 0xff, COMPARISON_EQUAL, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP);
|
|
|
|
//dsLitStencilLast = CG::me()->GetRenderer()->CreateDSState(true, false, COMPARISON_GREATER_EQUAL, true, 0xff, COMPARISON_EQUAL, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP);
|
|
|
|
PER_OBJECT_CONSTANTS constants;
|
|
constants.mWorld = LifeMath::float4x4();
|
|
|
|
rsCullBack = CG::me()->GetRenderer()->CreateRasterizerState(FILL_SOLID, CULL_BACK);
|
|
rsCullFront = CG::me()->GetRenderer()->CreateRasterizerState(FILL_SOLID, CULL_FRONT);
|
|
rsCullNone = CG::me()->GetRenderer()->CreateRasterizerState(FILL_SOLID, CULL_NONE);
|
|
|
|
//spotLightTex = ResourceManager::me()->GetTexture(String(_text("root/Data/Textures/Spotlight.dds")));
|
|
|
|
rootNode = new TransformGraphRootNode();
|
|
|
|
//sceneRt = CG::me()->GetRenderer()->CreateRenderTarget(width, height, FORMAT_R16G16B16A16_FLOAT);
|
|
|
|
sceneG_normal = CG::me()->GetRenderer()->CreateRenderTarget(width, height, FORMAT_R8G8B8A8_UNORM);
|
|
sceneG_color = CG::me()->GetRenderer()->CreateRenderTarget(width, height, FORMAT_R8G8B8A8_UNORM);
|
|
sceneG_depth = CG::me()->GetRenderer()->CreateRenderTarget(width, height, FORMAT_R16G16_FLOAT);
|
|
|
|
sceneLbuf = CG::me()->GetRenderer()->CreateRenderTarget(width, height, FORMAT_R16G16B16A16_FLOAT);
|
|
//sceneDt = CG::me()->GetRenderer()->CreateDepthTarget(width, height, FORMAT_D24_UNORM_S8_UINT);
|
|
|
|
lppPsSpot = ResourceManager::me()->CompileUserShaderPS(String(_text("Light_pre_pass_spot.psh")));
|
|
lppPsSpotShadow = ResourceManager::me()->CompileUserShaderPS(String(_text("Light_pre_pass_spot_shadow.psh")));
|
|
lppPsPoint = ResourceManager::me()->CompileUserShaderPS(String(_text("Light_pre_pass_point.psh")));
|
|
lppPsPointShadow = ResourceManager::me()->CompileUserShaderPS(String(_text("Light_pre_pass_point_shadow.psh")));
|
|
|
|
lppPsDirectional = ResourceManager::me()->CompileUserShaderPS(String(_text("Light_pre_pass_directional.psh")));
|
|
lppPsAmbient = ResourceManager::me()->CompileUserShaderPS(String(_text("Light_pre_pass_ambient.psh")));
|
|
|
|
lppVs = ResourceManager::me()->CompileUserShaderVS(String(_text("Light_pre_pass.vsh")));
|
|
|
|
lppPsStencilSphere = ResourceManager::me()->CompileUserShaderPS(String(_text("lighting/lpp_stencil_sphere.psh")));
|
|
lppVsStencilSphere = ResourceManager::me()->CompileUserShaderVS(String(_text("lighting/lpp_stencil_sphere.vsh")));
|
|
|
|
lppVsStencilCone = ResourceManager::me()->CompileUserShaderVS(String(_text("lighting/lpp_stencil_cone.vsh")));
|
|
|
|
psComposeFinal = ResourceManager::me()->CompileUserShaderPS(STR("LPP_Compose.psh"));
|
|
|
|
shadowManager = new ShadowMapManager();
|
|
shadowManager->Init(CG::me()->GetRenderer());
|
|
|
|
rpOmniShadow = new RenderPath::RenderPathOmniShadow(shadowManager);
|
|
rpSpotShadow = new RenderPath::RenderPathSpotShadow(shadowManager);
|
|
|
|
//fullscreen quad geometry
|
|
LPP_QUAD_VERT geometry[] =
|
|
{
|
|
LifeMath::float4(-1.0f,-1.0f,0.0f,1.0f), LifeMath::float3(0.0f,1.0f, 0.0f),
|
|
LifeMath::float4(-1.0f,1.0f,0.0f,1.0f), LifeMath::float3(0.0f,0.0f, 3.0f),
|
|
LifeMath::float4(1.0f,-1.0f,0.0f,1.0f), LifeMath::float3(1.0f,1.0f, 1.0f),
|
|
LifeMath::float4(1.0f,1.0f,0.0f,1.0f), LifeMath::float3(1.0f,0.0f, 2.0f),
|
|
};
|
|
|
|
lppQuadVb = CG::me()->GetRenderer()->CreateVertexBuffer(sizeof(LPP_QUAD_VERT) * 4, geometry, sizeof(LPP_QUAD_VERT));
|
|
|
|
IInputElement elements[] =
|
|
{
|
|
IInputElement("POSITION", 0, 0, FORMAT_R32G32B32A32_FLOAT, 0, 0, 0),
|
|
IInputElement("TEXCOORD", 0, 16, FORMAT_R32G32B32_FLOAT, 0, 0, 0),
|
|
};
|
|
lppInputLayout = CG::me()->GetRenderer()->CreateInputLayout(elements, 2, lppVs);
|
|
|
|
ISamplerDescription psDesc(Wrap, Wrap, Wrap, MinMagMipPoint);
|
|
ISamplerDescription pscDesc(Clamp, Clamp, Clamp, MinMagMipPoint);
|
|
ISamplerDescription lsDesc(Wrap, Wrap, Wrap, MinMagMipLinear);
|
|
|
|
pointSampler = CG::me()->GetRenderer()->CreateTextureSampler(&psDesc);
|
|
linearSampler = CG::me()->GetRenderer()->CreateTextureSampler(&lsDesc);
|
|
|
|
pointSamplerClamp = CG::me()->GetRenderer()->CreateTextureSampler(&pscDesc);
|
|
|
|
ssao = new PostSSAO(this, Q_MED);
|
|
lightCullSphere = ResourceManager::me()->GetMesh("root/Data/Objects/Sphere_stencil3_opt.vmf");
|
|
lightCullCone = ResourceManager::me()->GetMesh("root/Data/Objects/stencil_cone3_opt.vmf");
|
|
//
|
|
}
|
|
~IScene()
|
|
{
|
|
SAFE_DELETE(sceneG_depth);
|
|
SAFE_DELETE(sceneLbuf);
|
|
SAFE_DELETE(cbGlobal);
|
|
SAFE_DELETE(cbPerCamera);
|
|
SAFE_DELETE(cbPerCameraLight);
|
|
SAFE_DELETE(cbPointLights);
|
|
SAFE_DELETE(cbDirectionalLights);
|
|
SAFE_DELETE(cbSpotLights);
|
|
SAFE_DELETE(cbSkinData);
|
|
SAFE_DELETE(cbShadowInfo);
|
|
SAFE_DELETE(lppPsPoint);
|
|
SAFE_DELETE(lppPsSpot);
|
|
SAFE_DELETE(lppPsDirectional);
|
|
SAFE_DELETE(lppPsSpotShadow);
|
|
SAFE_DELETE(lppVs);
|
|
SAFE_DELETE(lppQuadVb);
|
|
SAFE_DELETE(lppInputLayout);
|
|
SAFE_DELETE(lppBlend);
|
|
SAFE_DELETE(gppBlend);
|
|
|
|
SAFE_DELETE(lppDepthState);
|
|
SAFE_DELETE(gppDepthState);
|
|
SAFE_DELETE(fppDepthState);
|
|
SAFE_DELETE(shadowManager);
|
|
SAFE_DELETE(pointSampler);
|
|
SAFE_DELETE(linearSampler);
|
|
SAFE_DELETE(postManager);
|
|
SAFE_DELETE(hdr);
|
|
SAFE_DELETE(plantManager);
|
|
SAFE_DELETE(terra);
|
|
SAFE_DELETE(sky);
|
|
SAFE_DELETE(pssm);
|
|
|
|
spotLightTex->Release();
|
|
}
|
|
|
|
LifeMath::Vec2i getOutputSize()
|
|
{
|
|
return LifeMath::Vec2i(outputWidth, outputHeight);
|
|
}
|
|
|
|
String name;
|
|
void Update(float dt)
|
|
{
|
|
timeElapsed = dt;
|
|
sceneTime += dt;
|
|
|
|
PER_SCENE_CONSTANTS globalConst;
|
|
globalConst.fTime = sceneTime;
|
|
globalConst.ambient = LifeMath::float3(0.05f,0.05f,0.05f);
|
|
globalConst.screenSize.X = (float)outputWidth;
|
|
globalConst.screenSize.Y = (float)outputHeight;
|
|
LifeMath::Vec2i sz = ssao->getSize();
|
|
globalConst.ssaoSize.X = (float)(sz.X);
|
|
globalConst.ssaoSize.Y = (float)(sz.Y);
|
|
cbGlobal->Update(&globalConst, sizeof(PER_SCENE_CONSTANTS));
|
|
|
|
CG::me()->GetRenderer()->SetVSConstantBuffer(cbGlobal, 0);
|
|
CG::me()->GetRenderer()->SetPSConstantBuffer(cbGlobal, 3);
|
|
|
|
int shadowedCount = 0;
|
|
for(std::vector<IGraphicsNode*>::iterator it = nodeList.begin(); it != nodeList.end(); ++it)
|
|
{
|
|
IGraphicsNode* l = *it;
|
|
l->update(timeElapsed);
|
|
if(l->getType() == NT_LIGHT)
|
|
{
|
|
if(mainCam->getFrustum()->SphereInFrustum(l->getBoundingSphere()))
|
|
{
|
|
Light* fl = static_cast<Light*>(l);
|
|
if(fl->lightType == LT_POINT)
|
|
visiblePointLights.push_back(fl);
|
|
else if(fl->lightType == LT_SPOT)
|
|
{
|
|
visibleSpotLights.push_back(fl);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(mainCam->getFrustum()->BoxInFrustum(l->getTransformedBox()))
|
|
{
|
|
visibleRenderables.push_back(l);
|
|
IObject* obj = static_cast<IObject*>(l);
|
|
bool transparent = false;
|
|
for(int k = 0; k< obj->getSumbeshCount(); k++)
|
|
{
|
|
IMaterialProxy* mat = obj->getMaterial(k);
|
|
//TODO
|
|
/*if(mat->Opaque)
|
|
transparent = true;*/
|
|
}
|
|
if(transparent)
|
|
{
|
|
visibleBlendRenderables.push_back(l);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Render(IRenderOutput* output)
|
|
{
|
|
renderer = CG::me()->GetRenderer();
|
|
renderer->SetBlendState(gppBlend);
|
|
renderer->SetPSTextureSampler(linearSampler, 0);
|
|
renderer->SetPSTextureSampler(pointSampler, 1);
|
|
|
|
//build g_buffer
|
|
int count = visibleRenderables.size();
|
|
|
|
PassDesc fpDesc;
|
|
fpDesc.camera = mainCam;
|
|
fpDesc.colorTarget = sceneG_depth;
|
|
fpDesc.depthTarget = output->GetSwapChain()->GetDepthBuffer(0);
|
|
fpDesc.frustum = mainCam->getFrustum();
|
|
fpDesc.type = PT_COMPOSE_G_BUF;
|
|
fpDesc.objectList.reserve(count);
|
|
for(int i = 0; i < count; i++)
|
|
fpDesc.objectList.push_back(visibleRenderables[i]);
|
|
passList.push_back(fpDesc);
|
|
|
|
//render shadows
|
|
/* PassDesc shadowDesc;
|
|
shadowDesc.type = PT_RENDER_SHADOW_MAP;
|
|
shadowDesc.objectList.reserve(visibleSpotLightsShadowed.size());
|
|
for(UINT i = 0; i< visibleSpotLightsShadowed.size(); i++)
|
|
shadowDesc.objectList.push_back(visibleSpotLightsShadowed[i]);
|
|
passList.push_back(shadowDesc);*/
|
|
|
|
if(sun)
|
|
{
|
|
PassDesc shadowPSSMDesc;
|
|
shadowPSSMDesc.type = PT_RENDER_SHADOW_MAP_PSSM;
|
|
shadowPSSMDesc.objectList.push_back(sun);
|
|
shadowPSSMDesc.camera = mainCam;
|
|
passList.push_back(shadowPSSMDesc);
|
|
}
|
|
|
|
//render lighting
|
|
PassDesc lightingDesc;
|
|
lightingDesc.camera = mainCam;
|
|
lightingDesc.colorTarget = sceneLbuf;
|
|
lightingDesc.depthTarget = output->GetSwapChain()->GetDepthBuffer(0);
|
|
lightingDesc.type = PT_LIGHTING;
|
|
passList.push_back(lightingDesc);
|
|
|
|
//final rendering
|
|
PassDesc finalDesc;
|
|
finalDesc.camera = mainCam;
|
|
finalDesc.colorTarget = output->GetSwapChain()->GetBackBuffer(0);
|
|
finalDesc.depthTarget = output->GetSwapChain()->GetDepthBuffer(0);
|
|
finalDesc.frustum = mainCam->getFrustum();
|
|
finalDesc.type = PT_COMPOSE_FINAL;
|
|
finalDesc.objectList.reserve(count);
|
|
for(int i = 0; i < count; i++)
|
|
finalDesc.objectList.push_back(visibleRenderables[i]);
|
|
passList.push_back(finalDesc);
|
|
|
|
for(UINT i = 0; i< passList.size(); i++)
|
|
{
|
|
doPass(&passList[i]);
|
|
}
|
|
|
|
|
|
|
|
visibleRenderables.clear();
|
|
visibleRenderablesShadow.clear();
|
|
visiblePointLights.clear();
|
|
visibleSpotLights.clear();
|
|
visibleBlendRenderables.clear();
|
|
|
|
// renderer->SetDepthStencilState(lppDepthState);
|
|
// ITexture2D* result = postManager->Execute(sceneRt, sceneDt, sceneGbuf, timeElapsed);
|
|
|
|
//render scene to LDR back buffer
|
|
renderer->UnbindResourcesPS();
|
|
//
|
|
|
|
|
|
//renderer->SetPSTexture(sceneRt, 0);
|
|
|
|
/*if(false)
|
|
{
|
|
renderer->SetColorTarget(output->GetSwapChain()->GetBackBuffer(0));
|
|
renderer->SetPSTexture(sceneLbuf, 0);
|
|
renderer->SetScissorRectangle(LifeMath::Rect2i(0, 0, outputWidth,outputHeight));
|
|
renderer->SetBlendState(gppBlend);
|
|
renderer->SetDepthStencilState(lppDepthState);
|
|
renderer->SetViewport(LifeMath::Rect2i(0,0,outputWidth,outputHeight));
|
|
renderer->SetPSTextureSampler(pointSampler, 0);
|
|
renderer->SetPSTextureSampler(pointSampler, 1);
|
|
renderer->RenderToTexture();
|
|
}
|
|
|
|
*/
|
|
|
|
passList.clear();
|
|
|
|
|
|
renderer->SetDepthStencilState(lppDepthState);
|
|
}
|
|
|
|
void doPass(PassDesc* desc)
|
|
{
|
|
LifeMath::float4 color(0.0f,0.0f,0.0f,0.0f);
|
|
int count = desc->objectList.size();
|
|
switch(desc->type)
|
|
{
|
|
case PT_COMPOSE_FINAL:
|
|
{
|
|
renderer->UnbindRenderTargets();
|
|
renderer->UnbindResourcesPS();
|
|
renderer->SetDepthStencilState(lppDepthState);
|
|
renderer->SetBlendState(gppBlend);
|
|
|
|
renderer->SetPSConstantBuffer(cbGlobal, 0);
|
|
|
|
renderer->SetPSTextureSampler(linearSampler, 0);
|
|
renderer->SetPSTextureSampler(pointSampler, 1);
|
|
|
|
renderer->SetTargets(desc->colorTarget, desc->depthTarget);
|
|
|
|
LifeMath::float4 clear_color(1,1,0,1);
|
|
renderer->ClearRenderTarget(desc->colorTarget, &clear_color);
|
|
|
|
renderer->SetPixelShader(psComposeFinal);
|
|
renderer->SetPSTexture(sceneG_normal, 0);
|
|
renderer->SetPSTexture(ssao->getTexture(), 1);
|
|
renderer->SetPSTexture(sceneG_depth, 2);
|
|
renderer->SetPSTexture(sceneLbuf, 3);
|
|
renderer->SetPSTexture(sceneG_color, 4);
|
|
|
|
LifeMath::Rect2i scr(0, 0, outputWidth, outputHeight);
|
|
renderer->SetScissorRectangle(scr);
|
|
renderer->SetViewport(scr);
|
|
|
|
renderer->RenderToTextureNoPs();
|
|
}
|
|
break;
|
|
case PT_COMPOSE_G_BUF:
|
|
{
|
|
if(terra)
|
|
terra->Update(desc->camera, sky->SunDirection);
|
|
if(plantManager)
|
|
plantManager->Update(timeElapsed, desc->camera);
|
|
|
|
renderer->UnbindResourcesPS();
|
|
renderer->UnbindRenderTargets();
|
|
|
|
const LifeMath::float3* corners = mainCam->getFrustum()->GetCorners();
|
|
|
|
LifeMath::Rect2i scr(0, 0, outputWidth, outputHeight);
|
|
renderer->SetScissorRectangle(scr);
|
|
renderer->SetViewport(scr);
|
|
|
|
//collect camera info
|
|
PER_CAMERA_CONSTANTS camConst;
|
|
camConst.mView = desc->camera->getView();
|
|
camConst.mProj = desc->camera->getProj();
|
|
camConst.mInvVP = camConst.mView * camConst.mProj;
|
|
camConst.corner0 = corners[0];
|
|
camConst.corner1 = corners[1];
|
|
camConst.corner2 = corners[2];
|
|
camConst.corner3 = corners[3];
|
|
LifeMath::float3 camPos = desc->camera->getPosition();
|
|
LifeMath::float3 camDir = desc->camera->getDirection();
|
|
camConst.camPos = camPos;
|
|
camConst.camDir = camDir;
|
|
camConst.camNearFar.X = desc->camera->getNear();
|
|
camConst.camNearFar.Y = desc->camera->getFar();
|
|
camConst.camNearFar.Z = static_cast<float>(outputWidth);
|
|
camConst.camNearFar.W = static_cast<float>(outputHeight);
|
|
cbPerCamera->Update(&camConst, sizeof(PER_CAMERA_CONSTANTS));
|
|
|
|
renderer->SetDepthStencilState(gppDepthState);
|
|
renderer->SetVSConstantBuffer(cbPerCamera, 1);
|
|
renderer->SetPSConstantBuffer(cbPerCamera, 1);
|
|
|
|
|
|
|
|
ITexture2D* tex[] = {sceneG_color, sceneG_normal, desc->colorTarget};
|
|
// ITexture2D* tex2[] = {brdfTex, desc->colorTarget};
|
|
renderer->SetTargets(tex, 3, desc->depthTarget);
|
|
/*renderer->SetTargets(tex2, 2,desc->depthTarget);
|
|
renderer->SetTargets(tex, 2,desc->depthTarget);
|
|
renderer->SetTargets(tex2, 2,desc->depthTarget);*/
|
|
|
|
LifeMath::float4 clearColor;
|
|
clearColor.X = 0.0f;
|
|
clearColor.Y = 0.0f;
|
|
clearColor.Z = 0.0f;
|
|
clearColor.W = 0.0f;
|
|
|
|
LifeMath::float4 clearColor2(0,0,0,0);
|
|
|
|
//clear g-buffer and brdf texture
|
|
renderer->ClearRenderTarget(desc->colorTarget, &clearColor);
|
|
renderer->ClearRenderTarget(sceneG_normal, &clearColor);
|
|
renderer->ClearRenderTarget(sceneG_color, &clearColor2);
|
|
|
|
renderer->ClearDepthStencil(desc->depthTarget, 1.0f, 0);
|
|
|
|
LifeMath::float4 col(0.2f,0.2f,0.2f,1);
|
|
renderer->ClearRenderTarget(sceneG_color, &col);
|
|
|
|
|
|
if(terra)
|
|
terra->Render(PT_COMPOSE_G_BUF);
|
|
|
|
if(plantManager)
|
|
plantManager->Render(PT_COMPOSE_G_BUF);
|
|
|
|
for(int i = 0; i < count; i++)
|
|
{
|
|
IObject* mesh = static_cast<IObject*>(desc->objectList[i]);
|
|
|
|
mesh->bind();
|
|
for(int i = 0; i<mesh->getSumbeshCount(); i++)
|
|
{
|
|
IMaterialProxy* mat = mesh->getMaterial(i);
|
|
mat->SelectTechnique(MT_RENDER_DEFERRED);
|
|
mat->GetTechnique()->SelectPass(MP_G_FILL);
|
|
|
|
IMaterialPass* pass = mat->GetTechnique()->GetPass();
|
|
//renderer->SetPixelShader(pass->GetShader(ST_PS));
|
|
//renderer->SetVertexShader(pass->GetShader(ST_VS));
|
|
|
|
IConstantBuffer* cb_mat = pass->GetConstantBuffer();
|
|
if(cb_mat!= nullptr) renderer->SetPSConstantBuffer(cb_mat, 2);
|
|
pass->Apply();
|
|
mesh->render(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
//SSAO
|
|
/* renderer->SetPSConstantBuffer(cbGlobal, 0);
|
|
renderer->SetVSConstantBuffer(cbGlobal, 0);
|
|
ssao->process(cbPerCamera, sceneGbuf, sceneDt);*/
|
|
|
|
/* renderer->UnbindRenderTargets();
|
|
renderer->SetTargets(sceneSsao, sceneDt);
|
|
|
|
renderer->SetPSTexture(sceneSsaoBlur, 0);
|
|
renderer->SetPSTexture(sceneGbuf, 9);
|
|
renderer->SetPixelShader(psSSAOBlur2);
|
|
renderer->Draw(4,0);*/
|
|
|
|
// printf("SSAO time: %f\n", timer.getTimeElapsed());
|
|
|
|
renderer->SetPrimitiveTopology(PT_TRIANGLE_LIST);
|
|
renderer->SetPSTextureSampler(linearSampler, 0);
|
|
renderer->SetPSTextureSampler(pointSampler, 1);
|
|
|
|
break;
|
|
case PT_RENDER_SHADOW_MAP:
|
|
{
|
|
/*if(desc->objectList.size() > 0)
|
|
{
|
|
shadowManager->beginShadowRendering(desc->objectList.size());
|
|
for(UINT i = 0; i< desc->objectList.size(); i++)
|
|
{
|
|
Light* l = static_cast<Light*>(desc->objectList[i]);
|
|
shadowManager->beginLightRender(l);
|
|
|
|
//collect light camera info
|
|
PER_CAMERA_CONSTANTS pccs = {0};
|
|
pccs.camNearFar = LifeMath::float4(0.1f, l->getRange(), 0.0f,0.0f);
|
|
pccs.mView = l->getView();
|
|
pccs.mProj = l->getProj();
|
|
LifeMath::float3camPosl = l->getPosition();
|
|
LifeMath::float3camDirl = l->getDirection();
|
|
pccs.camPos = camPosl;
|
|
pccs.camDir = camDirl;
|
|
cbPerCameraLight->Update(&pccs, sizeof(PER_CAMERA_CONSTANTS));
|
|
renderer->SetVSConstantBuffer(cbPerCameraLight, 1);
|
|
renderer->SetPSConstantBuffer(cbPerCameraLight, 1);
|
|
|
|
//cull scene to take all visible to light geometry
|
|
for(std::vector<IGraphicsNode*>::iterator it = nodeList.begin(); it != nodeList.end(); it++)
|
|
{
|
|
IGraphicsNode* obj = *it;
|
|
if(obj->getType() != NT_LIGHT && l->getFrustum()->SphereInFrustum(obj->getBoundingSphere()))
|
|
{
|
|
IObject* m = (IObject*)obj;
|
|
if(m->castShadows)
|
|
visibleRenderablesShadow.push_back(obj);
|
|
}
|
|
}
|
|
|
|
//render objects to shadow map
|
|
int count = visibleRenderablesShadow.size();
|
|
for(int i = 0; i < count; i++)
|
|
{
|
|
IObject* mesh = static_cast<IObject*>(visibleRenderablesShadow[i]);
|
|
mesh->bind();
|
|
|
|
for(int i = 0; i < mesh->getSumbeshCount(); i++)
|
|
{
|
|
IMaterial* mat = mesh->getMaterial(i);
|
|
if(!mat->AlphaBlendEnable)
|
|
{
|
|
renderer->SetVertexShader(mat->vertexShader);
|
|
|
|
if(mat->diffuseMap.ptr())
|
|
{
|
|
renderer->SetPSTexture(mat->diffuseMap.ptr(), 0);
|
|
}
|
|
if(mat->AlphaTest || mat->AlphaBlendEnable)
|
|
{
|
|
renderer->SetPixelShader(shadowManager->rtdPsAT);
|
|
}
|
|
else
|
|
{
|
|
renderer->SetPixelShader(shadowManager->rtdPs);
|
|
}
|
|
mesh->render(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
shadowManager->endLightRender();
|
|
}
|
|
}*/
|
|
}
|
|
break;
|
|
case PT_RENDER_SHADOW_MAP_PSSM:
|
|
{
|
|
renderer->SetPSTextureSampler(linearSampler, 0);
|
|
renderer->SetPSTextureSampler(pointSampler, 1);
|
|
|
|
visibleRenderablesShadow.clear();
|
|
//if(desc->objectList.size() > 0)
|
|
//{
|
|
sun->setDirection(sky->SunDirection);
|
|
pssm->Begin(desc->camera, sun);
|
|
int splitCount = pssm->splitCount;
|
|
|
|
for(int i = 0; i<splitCount; i++)
|
|
{
|
|
/*pssm->BeginSplit(i);
|
|
Frustum* f = &pssm->f;
|
|
//cull scene to take all visible to light geometry
|
|
for(std::vector<IGraphicsNode*>::iterator it = nodeList.begin(); it != nodeList.end(); it++)
|
|
{
|
|
IGraphicsNode* obj = *it;
|
|
if(obj->getType() != NT_LIGHT && f->BoxInFrustum(obj->getTransformedBox()))
|
|
{
|
|
IMesh* m = (IMesh*)obj;
|
|
if(m->castShadows)
|
|
visibleRenderablesShadow.push_back(obj);
|
|
}
|
|
}
|
|
|
|
PER_CAMERA_CONSTANTS pccs = {0};
|
|
|
|
pccs.camNearFar = LifeMath::float4(pssm->fNear, pssm->fFar, 0.0f,0.0f);
|
|
|
|
pccs.mView = pssm->mLightView;
|
|
pccs.mProj = pssm->mLightProj;
|
|
pccs.mInvVP = pssm->mLightView * pssm->mLightProj;
|
|
|
|
LifeMath::float3camPosl = pssm->vLightSource;
|
|
LifeMath::float3camDirl = pssm->vLightTarget;
|
|
|
|
pccs.camPos = camPosl;
|
|
|
|
pccs.camDir = camDirl;
|
|
|
|
cbPerCameraLight->Update(&pccs, sizeof(PER_CAMERA_CONSTANTS));
|
|
renderer->SetVSConstantBuffer(cbPerCameraLight, 1);
|
|
renderer->SetPSConstantBuffer(cbPerCameraLight, 1);
|
|
|
|
renderer->SetVSConstantBuffer(cbGlobal, 0);
|
|
plantManager->Render(PT_RENDER_SHADOW_MAP_PSSM);
|
|
|
|
//render objects to shadow map
|
|
int count = visibleRenderablesShadow.size();
|
|
for(int i = 0; i < count; i++)
|
|
{
|
|
IMesh* mesh = static_cast<IMesh*>(visibleRenderablesShadow[i]);
|
|
PER_OBJECT_CONSTANTS objConst;
|
|
objConst.mWorld = mesh->getTransform()->GetMatrix();
|
|
cbPerObject->Update(&objConst, sizeof(PER_OBJECT_CONSTANTS));
|
|
|
|
if (mesh->IsSkinned)
|
|
{
|
|
PerObjectSkinningVSData skinData;
|
|
skinData.mWorld = new LifeMath::float4x4[MAX_BONES_COUNT];
|
|
|
|
mesh->skin.skeleton.GetMatrices(skinData.mWorld);
|
|
|
|
cbSkinData->Update(skinData.mWorld, PerObjectSkinningVSDataSize);
|
|
|
|
renderer->SetVSConstantBuffer(cbSkinData, 5);
|
|
delete[] skinData.mWorld;
|
|
}
|
|
|
|
renderer->SetVSConstantBuffer(cbPerObject, 0);
|
|
/*renderer->SetVertexBuffer(mesh->vertexData);
|
|
renderer->SetIndexBuffer(mesh->indexData);
|
|
|
|
renderer->SetInputLayout(mesh->inputLayout);
|
|
renderer->SetPrimitiveTopology(PT_TRIANGLE_LIST);
|
|
for(int j = 0; j < mesh->subsetCount; j++)
|
|
{
|
|
IMaterial* mat = &mesh->subsets[j].material;
|
|
//renderer->SetPixelShader(mat->g_buffer_pass_ps);
|
|
renderer->SetVertexShader(mat->vertexShader);
|
|
|
|
if(mat->diffuseMap.ptr())
|
|
{
|
|
renderer->SetPSTexture(mat->diffuseMap.ptr(), 0);
|
|
//renderer->SetPSTexture(mat->normalMap.ptr(), 2);
|
|
}
|
|
renderer->DrawIndexed(mesh->subsets[j].Offset,mesh->subsets[j].Length);
|
|
}
|
|
}
|
|
|
|
pssm->EndSplit();*/
|
|
}
|
|
pssm->End();
|
|
renderer->SetVSConstantBuffer(cbGlobal, 0); //set back global cb //FIX IT: per object constant buffer should not be set to slot 0 !!
|
|
}
|
|
break;
|
|
case PT_LIGHTING:
|
|
{
|
|
renderer->UnbindResourcesPS();
|
|
renderer->UnbindRenderTargets();
|
|
|
|
renderer->SetPSTexture(sceneG_depth, 0);
|
|
renderer->SetPSTexture(sceneG_color, 1);
|
|
renderer->SetPSTexture(sceneG_normal, 9);
|
|
|
|
renderer->SetTargets(desc->colorTarget, desc->depthTarget);
|
|
//-----begin lighting
|
|
renderer->SetVSConstantBuffer(cbPerCamera, 1);
|
|
renderer->SetPSConstantBuffer(cbPerCamera, 1);
|
|
renderer->SetViewport(LifeMath::Rect2i(0, 0, outputWidth, outputHeight));
|
|
|
|
renderer->SetDepthStencilState(lppDepthState);
|
|
|
|
LifeMath::float4 clear_color(0,0,0,0);
|
|
renderer->ClearRenderTarget(desc->colorTarget, &clear_color);
|
|
|
|
renderer->SetInputLayout(lppInputLayout);
|
|
renderer->SetBlendState(lppBlend);
|
|
renderer->SetVertexBuffer(lppQuadVb);
|
|
renderer->SetPrimitiveTopology(PT_TRIANGLE_STRIP);
|
|
renderer->SetVertexShader(lppVs);
|
|
|
|
//render sun
|
|
if(sun)
|
|
{
|
|
pssm->UpdateBuffer();
|
|
//renderer->SetPSTexture(pssm->depth, 1); //NEED TO SELECT DiFFERENT TEXTURE SLOT! 1 IS FOR DIFFuSE NOW
|
|
renderer->SetPSConstantBuffer(pssm->cbPssm, 3);
|
|
|
|
renderer->SetPixelShader(lppPsDirectional);
|
|
renderer->SetPSConstantBuffer(cbDirectionalLights, 2);
|
|
DIR_LIGHT_DATA dlightData;
|
|
LifeMath::float4x4 invVP2 = desc->camera->getView() * desc->camera->getProj();
|
|
|
|
Light* l = sun;
|
|
LifeMath::float3 dir = sky->SunDirection;
|
|
LifeMath::Vec3Normalize(&dir);
|
|
|
|
dlightData.Direction = dir;
|
|
dlightData.Intensity = l->intensity;
|
|
|
|
dlightData.Color.X = l->color.X;
|
|
dlightData.Color.Y = l->color.Y;
|
|
dlightData.Color.Z = l->color.Z;
|
|
|
|
dlightData.SpecularPow = 30.0f;
|
|
cbDirectionalLights->Update(&dlightData, sizeof(DIR_LIGHT_DATA));
|
|
//
|
|
renderer->Draw(4,0);
|
|
}
|
|
|
|
//-----render point lights
|
|
int countL = visiblePointLights.size();
|
|
if(countL)
|
|
{
|
|
renderer->SetDepthStencilState(lppDepthState);
|
|
|
|
renderer->SetTargets(desc->colorTarget, desc->depthTarget);
|
|
renderer->SetVSConstantBuffer(cbPerCamera, 1);
|
|
renderer->SetPSConstantBuffer(cbPerCamera, 1);
|
|
|
|
renderer->SetPSConstantBuffer(cbPointLights, 2);
|
|
renderer->SetVSConstantBuffer(cbPointLights, 2);
|
|
renderer->SetPixelShader(lppPsPoint);
|
|
renderer->SetVertexShader(lppVsStencilSphere);
|
|
|
|
renderer->SetPSTexture(sceneG_depth, 0);
|
|
renderer->SetPSTexture(sceneG_color, 1);
|
|
renderer->SetPSTexture(sceneG_normal, 9);
|
|
|
|
//sceneG_color->ToFile("C:\\color.dds");
|
|
//bind sphere mesh
|
|
renderer->SetIndexBuffer(lightCullSphere->indexData);
|
|
renderer->SetVertexBuffer(lightCullSphere->vertexData);
|
|
renderer->SetPrimitiveTopology(PT_TRIANGLE_LIST);
|
|
renderer->SetInputLayout(lightCullSphere->inputLayout);
|
|
|
|
POINT_LIGHT_DATA lightData;
|
|
LifeMath::float4x4 invVP2 = desc->camera->getView() * desc->camera->getProj();
|
|
|
|
renderer->ClearDepthStencil(desc->depthTarget, 2, 1, 0);
|
|
|
|
for(int i = 0; i < countL; i++)
|
|
{
|
|
Light* l = visiblePointLights[i];
|
|
|
|
if(l->castShadows)
|
|
{
|
|
renderer->SetDepthStencilState(gppDepthState);
|
|
renderer->SetBlendState(gppBlend);
|
|
rpOmniShadow->SetLight(*visiblePointLights[i]);
|
|
rpOmniShadow->Render(this);
|
|
|
|
renderer->SetViewport(LifeMath::Rect2i(0, 0, outputWidth, outputHeight));
|
|
|
|
renderer->SetTargets(desc->colorTarget, desc->depthTarget);
|
|
renderer->SetVSConstantBuffer(cbPerCamera, 1);
|
|
renderer->SetPSConstantBuffer(cbPerCamera, 1);
|
|
|
|
renderer->SetPSConstantBuffer(cbPointLights, 2);
|
|
renderer->SetVSConstantBuffer(cbPointLights, 2);
|
|
|
|
renderer->SetPSTexture(sceneG_depth, 0);
|
|
renderer->SetPSTexture(sceneG_color, 1);
|
|
renderer->SetPSTexture(sceneG_normal, 9);
|
|
renderer->SetPSTextureCube(rpOmniShadow->GetShadowMap(), 8);
|
|
|
|
renderer->SetPixelShader(lppPsPointShadow);
|
|
renderer->SetVertexShader(lppVsStencilSphere);
|
|
|
|
renderer->SetIndexBuffer(lightCullSphere->indexData);
|
|
renderer->SetVertexBuffer(lightCullSphere->vertexData);
|
|
renderer->SetPrimitiveTopology(PT_TRIANGLE_LIST);
|
|
renderer->SetInputLayout(lightCullSphere->inputLayout);
|
|
}
|
|
else
|
|
{
|
|
renderer->SetPixelShader(lppPsPoint);
|
|
}
|
|
//setup light constants
|
|
LifeMath::float3 pos = l->getPosition();
|
|
lightData.Position = pos;
|
|
lightData.Intensity = l->intensity;
|
|
lightData.Color.X = l->color.X;
|
|
lightData.Color.Y = l->color.Y;
|
|
lightData.Color.Z = l->color.Z;
|
|
lightData.Range = l->getRange();
|
|
cbPointLights->Update(&lightData, sizeof(POINT_LIGHT_DATA));
|
|
|
|
renderer->SetRasterizerState(rsCullBack);
|
|
renderer->SetDepthStencilState(dsLitStencilOne, 0);
|
|
renderer->SetBlendState(bsNoWrite);
|
|
renderer->DrawIndexed(0, lightCullSphere->subsets[0].Length, 0);
|
|
|
|
renderer->SetRasterizerState(rsCullFront);
|
|
renderer->SetDepthStencilState(dsLitStencilTwo, 0);
|
|
renderer->SetBlendState(lppBlend);
|
|
renderer->DrawIndexed(0, lightCullSphere->subsets[0].Length, 0);
|
|
}
|
|
}
|
|
|
|
renderer->SetRasterizerState(rsCullBack);
|
|
|
|
//render spot lights
|
|
int spotCount = visibleSpotLights.size();
|
|
if(spotCount)
|
|
{
|
|
renderer->UnbindResourcesPS();
|
|
renderer->SetPSConstantBuffer(cbSpotLights, 3);
|
|
renderer->SetVertexShader(lppVs);
|
|
SPOT_LIGHT_DATA lightDataSpot;
|
|
renderer->SetPSTexture(sceneG_depth, 0);
|
|
renderer->SetPSTexture(sceneG_color, 1);
|
|
renderer->SetPSTexture(sceneG_normal, 9);
|
|
for(int i = 0; i < spotCount; i++)
|
|
{
|
|
Light* l = visibleSpotLights[i];
|
|
renderer->SetPSTextureSampler(linearSampler, 0);
|
|
renderer->SetPSTextureSampler(pointSampler, 1);
|
|
|
|
if(l->castShadows)
|
|
{
|
|
renderer->SetBlendState(gppBlend);
|
|
rpSpotShadow->SetLight(*l);
|
|
rpSpotShadow->Render(this);
|
|
|
|
renderer->SetViewport(LifeMath::Rect2i(0, 0, outputWidth, outputHeight));
|
|
renderer->SetTargets(desc->colorTarget, desc->depthTarget);
|
|
|
|
renderer->SetVSConstantBuffer(cbPerCamera, 1);
|
|
renderer->SetPSConstantBuffer(cbPerCamera, 1);
|
|
|
|
renderer->SetPSTexture(rpSpotShadow->GetShadowMap(), 6);
|
|
|
|
renderer->SetPSTextureSampler(linearSampler, 0);
|
|
renderer->SetPSTextureSampler(pointSampler, 1);
|
|
|
|
renderer->SetVertexShader(lppVs);
|
|
renderer->SetPixelShader(lppPsSpotShadow);
|
|
|
|
renderer->SetPSTexture(sceneG_depth, 0);
|
|
renderer->SetPSTexture(sceneG_color, 1);
|
|
renderer->SetPSTexture(sceneG_normal, 9);
|
|
}
|
|
else
|
|
{
|
|
renderer->SetPixelShader(lppPsSpot);
|
|
}
|
|
|
|
renderer->SetPSTexture(spotLightTex.ptr(), 4);
|
|
|
|
SHADOW_DATA shadowInfo = shadowManager->getShadowInfo(i);
|
|
cbShadowInfo->Update(&shadowInfo, sizeof(SHADOW_DATA));
|
|
|
|
LifeMath::float3 pos = l->getPosition();
|
|
|
|
LifeMath::Rect2i rect(0, 0, outputWidth, outputHeight);
|
|
|
|
renderer->SetScissorRectangle(rect);
|
|
|
|
lightDataSpot.Position = pos;
|
|
lightDataSpot.Direction = l->getDirection() - l->getPosition();
|
|
LifeMath::Vec3Normalize(&lightDataSpot.Direction);
|
|
lightDataSpot.Intensity = l->intensity;
|
|
lightDataSpot.Color = l->color;
|
|
lightDataSpot.Range = l->getRange();
|
|
lightDataSpot.InnerAngle = cosf(l->getInnerAngle() * 0.5f);
|
|
lightDataSpot.OuterAngle = cosf(l->getOuterAngle() * 0.5f);
|
|
lightDataSpot.lightMatrix = l->getMatrix();
|
|
lightDataSpot.lightView = l->getView();
|
|
lightDataSpot.meshMatrix = l->getMeshMatrix();
|
|
|
|
lightDataSpot.ZNear = 0.1f;
|
|
//Mat4x4Identity(&lightDataSpot.meshMatrix);
|
|
cbSpotLights->Update(&lightDataSpot, sizeof(SPOT_LIGHT_DATA));
|
|
|
|
renderer->SetVertexShader(lppVsStencilCone);
|
|
|
|
//setup cone geometry
|
|
renderer->SetVertexBuffer(lightCullCone->vertexData);
|
|
renderer->SetIndexBuffer(lightCullCone->indexData);
|
|
renderer->SetInputLayout(lightCullCone->inputLayout);
|
|
renderer->SetPrimitiveTopology(PT_TRIANGLE_LIST);
|
|
|
|
renderer->SetPSConstantBuffer(cbSpotLights, 3);
|
|
renderer->SetVSConstantBuffer(cbSpotLights, 3);
|
|
|
|
renderer->SetRasterizerState(rsCullBack);
|
|
renderer->SetDepthStencilState(dsLitStencilOne, 0);
|
|
renderer->SetBlendState(bsNoWrite);
|
|
renderer->DrawIndexed(0, lightCullCone->subsets[0].Length, 0);
|
|
|
|
renderer->SetRasterizerState(rsCullFront);
|
|
renderer->SetDepthStencilState(dsLitStencilTwo, 0);
|
|
renderer->SetBlendState(lppBlend);
|
|
renderer->DrawIndexed(0, lightCullCone->subsets[0].Length, 0);
|
|
}
|
|
}
|
|
|
|
//end lighting
|
|
LifeMath::Rect2i rect2(0,0,outputWidth, outputHeight);
|
|
renderer->SetScissorRectangle(rect2);
|
|
renderer->SetBlendState(gppBlend);
|
|
renderer->SetDepthStencilState(fppDepthState);
|
|
|
|
renderer->UnbindResourcesPS();
|
|
renderer->UnbindRenderTargets();
|
|
}
|
|
break;
|
|
}
|
|
desc->objectList.clear();
|
|
}
|
|
|
|
void PushNode(IGraphicsNode* node)
|
|
{
|
|
//if(node->Id >=0)
|
|
//{
|
|
if(node->getType() == NT_LIGHT)
|
|
{
|
|
Light* l = static_cast<Light*>(node);
|
|
if(l->lightType == LT_DIRECTIONAL)
|
|
sun = l;
|
|
else
|
|
nodeList.push_back(node);
|
|
rootNode->addChild(node);
|
|
}
|
|
else
|
|
{
|
|
nodeList.push_back(node);
|
|
rootNode->addChild(node);
|
|
}
|
|
|
|
//}
|
|
//else
|
|
//{
|
|
// return;
|
|
//}
|
|
}
|
|
|
|
void PerformQuery(IFrustumQuery* query)
|
|
{
|
|
for(std::vector<IGraphicsNode*>::iterator it = nodeList.begin(); it != nodeList.end(); ++it)
|
|
{
|
|
IGraphicsNode* l = *it;
|
|
|
|
if(!query->Filration || (((query->filter & l->getType()) !=0)))
|
|
{
|
|
if(l->getType() == NT_LIGHT)
|
|
{
|
|
if(query->GetFrustum().SphereInFrustum(l->getBoundingSphere()))
|
|
{
|
|
query->AddNode(l);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(query->GetFrustum().BoxInFrustum(l->getTransformedBox()))
|
|
{
|
|
query->AddNode(l);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
private:
|
|
IMesh* lightCullSphere;
|
|
IMesh* lightCullCone;
|
|
|
|
IRenderer* renderer;
|
|
float angle;
|
|
LifeCore::BoundingBox3D lbb;
|
|
LifeMath::float3 lbbCorners[8];
|
|
//ITexture2D* sceneRt;
|
|
ITexture2D* sceneLbuf;
|
|
//ITexture2D* sceneDt;
|
|
|
|
ITexture2D* sceneG_depth;
|
|
ITexture2D* sceneG_color;
|
|
ITexture2D* sceneG_normal;
|
|
|
|
texture_ptr ssaoRandom;
|
|
|
|
std::vector<IGraphicsNode*> nodeList;
|
|
IGraphicsNode* rootNode;
|
|
IConstantBuffer* cbGlobal;
|
|
IConstantBuffer* cbPerCamera;
|
|
IConstantBuffer* cbPerCameraLight;
|
|
IConstantBuffer* cbPointLights;
|
|
IConstantBuffer* cbDirectionalLights;
|
|
IConstantBuffer* cbSpotLights;
|
|
IConstantBuffer* cbSkinData;
|
|
|
|
IConstantBuffer* cbStencilSphere;
|
|
|
|
IConstantBuffer* cbShadowInfo;
|
|
|
|
RenderQueue renderableQueue;
|
|
std::vector<IGraphicsNode*> visibleRenderables;
|
|
std::vector<IGraphicsNode*> visibleRenderablesShadow;
|
|
std::vector<Light*> visiblePointLights;
|
|
std::vector<Light*> visibleSpotLights;
|
|
std::vector<IGraphicsNode*> visibleBlendRenderables;
|
|
Light* sun;
|
|
IShader* lppPsPoint;
|
|
IShader* lppPsPointShadow;
|
|
IShader* lppPsSpot;
|
|
IShader* lppPsDirectional;
|
|
IShader* lppPsSpotShadow;
|
|
IShader* lppPsAmbient;
|
|
IShader* lppPsStencilSphere;
|
|
IShader* lppVsStencilSphere;
|
|
IShader* lppVsStencilCone;
|
|
IShader* lppVs;
|
|
IShader* psComposeFinal;
|
|
IShader* psDownSampleDepth;
|
|
IVertexBuffer* lppQuadVb;
|
|
IInputLayout* lppInputLayout;
|
|
IBlendState* lppBlend;
|
|
IBlendState* gppBlend;
|
|
|
|
IBlendState* appBlend;
|
|
IBlendState* bsNoWrite;
|
|
|
|
IDepthStencilState* lppDepthState;
|
|
IDepthStencilState* gppDepthState;
|
|
IDepthStencilState* fppDepthState;
|
|
IDepthStencilState* dsLitStencilOne;
|
|
IDepthStencilState* dsLitStencilTwo;
|
|
IDepthStencilState* dsLitStencilLast;
|
|
IDepthStencilState* dsLitStencilLast2;
|
|
|
|
ShadowMapManager* shadowManager;
|
|
texture_ptr spotLightTex;
|
|
|
|
std::vector<PassDesc> passList;
|
|
|
|
ITextureSampler* pointSampler;
|
|
ITextureSampler* linearSampler;
|
|
|
|
ITextureSampler* pointSamplerClamp;
|
|
|
|
IRasterizerState* rsCullBack;
|
|
IRasterizerState* rsCullFront;
|
|
IRasterizerState* rsCullNone;
|
|
|
|
int outputWidth;
|
|
int outputHeight;
|
|
|
|
PostEffectManager* postManager;
|
|
|
|
PostHDR* hdr;
|
|
PostDOF* dof;
|
|
PostSSAO* ssao;
|
|
PlantManager* plantManager;
|
|
|
|
Terrain* terra;
|
|
Sky* sky;
|
|
float timeElapsed;
|
|
|
|
passPSSM* pssm;
|
|
|
|
float sceneTime;
|
|
|
|
LifeCore::Timer timer;
|
|
IObjectMesh* tm;
|
|
RenderPath::RenderPathOmniShadow* rpOmniShadow;
|
|
RenderPath::RenderPathSpotShadow* rpSpotShadow;
|
|
};
|
|
}
|
|
|
|
#endif // IScene_h__
|