Files
LifeProject/LifeGraphics/IScene.h
T

1203 lines
39 KiB
C++
Raw Normal View History

2025-05-13 02:46:21 +03:00
#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__