#ifndef IScene_h__ #define IScene_h__ #define _CRTDBG_MAP_ALLOC #include #include #include "LifeDebug.h" #include "IGraphicsNode.h" #include "LString.h" #include #include //#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 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::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(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(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(outputWidth); camConst.camNearFar.W = static_cast(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(desc->objectList[i]); mesh->bind(); for(int i = 0; igetSumbeshCount(); 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(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::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(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; iBeginSplit(i); Frustum* f = &pssm->f; //cull scene to take all visible to light geometry for(std::vector::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(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(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::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 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 visibleRenderables; std::vector visibleRenderablesShadow; std::vector visiblePointLights; std::vector visibleSpotLights; std::vector 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 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__