*
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
#ifndef ShadowMapManager_h__
|
||||
#define ShadowMapManager_h__
|
||||
|
||||
#include "render/IRenderer.h"
|
||||
#include <vector>
|
||||
#include "math/Vector4D.h"
|
||||
#include "math/Vector2D.h"
|
||||
#include "Rectangle2D.h"
|
||||
#include "math/Matrix4x4.h"
|
||||
#include "Light.h"
|
||||
#include "Globals.h"
|
||||
#include <float.h>
|
||||
|
||||
namespace LifeGraphics
|
||||
{
|
||||
struct SHADOW_DATA
|
||||
{
|
||||
LifeMath::float4 uvOffset_uvScale;
|
||||
LifeMath::float4 shadowMapTexelSize_dummy;
|
||||
};
|
||||
|
||||
class ShadowMapManager
|
||||
{
|
||||
private:
|
||||
IRenderer* renderer;
|
||||
int shadowMapResolution;
|
||||
std::vector<LifeMath::float4> texRegions;
|
||||
std::vector<LifeMath::Rect2i> viewRegions;
|
||||
ITexture2D* depthBuffer;
|
||||
ITexture2D* shadowBuffer;
|
||||
IBlendState* restoreBlendState;
|
||||
|
||||
LifeMath::float4x4 lightMatrices[4];
|
||||
int curLightIndex;
|
||||
IBlendState* shadowBlendState;
|
||||
|
||||
void ComputeDepthRegionDistribution(int lightCount)
|
||||
{
|
||||
texRegions.clear();
|
||||
viewRegions.clear();
|
||||
printf("SHOULD FIX RECTANGLES!!!!!!!!!!!!!!!!!!!!! NOT COORD! WIDTH!!!!!!!!!!!!!!! ComputeDepthRegionDistribution\n");
|
||||
switch (lightCount)
|
||||
{
|
||||
case 1:
|
||||
//----------|
|
||||
//| |
|
||||
//| 1 |
|
||||
//| |
|
||||
//| |
|
||||
//----------|
|
||||
|
||||
texRegions.push_back(LifeMath::float4(0.0f, 0.0f, 1.0f, 1.0f));
|
||||
viewRegions.push_back(LifeMath::Rect2i(0, 0, shadowMapResolution, shadowMapResolution));
|
||||
break;
|
||||
case 2:
|
||||
//----------|
|
||||
//| 1 |
|
||||
//| |
|
||||
//-----------
|
||||
//| |
|
||||
//| 2 |
|
||||
//----------|
|
||||
/*texRegions.push_back(LifeMath::float4(0.0f, 0.0f, 1.0f, 0.5f));
|
||||
viewRegions.push_back(Rectangle2D(0.0f, 0.0f, shadowMapResolution2, shadowMapResolution2 / 2));
|
||||
|
||||
texRegions.push_back(LifeMath::float4(0.0f, 0.5f, 1.0f, 0.5f));
|
||||
viewRegions.push_back(Rectangle2D(0.0f, shadowMapResolution2 / 2, shadowMapResolution2, shadowMapResolution2 / 2));*/
|
||||
|
||||
texRegions.push_back(LifeMath::float4(0.0f, 0.0f, 1.0f, 0.5f));
|
||||
viewRegions.push_back(LifeMath::Rect2i(0, 0, shadowMapResolution, shadowMapResolution / 2));
|
||||
|
||||
texRegions.push_back(LifeMath::float4(0.0f, 0.5f, 1.0f, 0.5f));
|
||||
viewRegions.push_back(LifeMath::Rect2i(0, shadowMapResolution / 2, shadowMapResolution, shadowMapResolution));
|
||||
|
||||
break;
|
||||
case 3:
|
||||
texRegions.push_back(LifeMath::float4(0.0f, 0.0f, 1.0f, 0.5f));
|
||||
viewRegions.push_back(LifeMath::Rect2i(0, 0, shadowMapResolution, shadowMapResolution / 2));
|
||||
|
||||
texRegions.push_back(LifeMath::float4(0.0f, 0.5f, 0.5f, 0.5f));
|
||||
viewRegions.push_back(LifeMath::Rect2i(0, shadowMapResolution / 2, shadowMapResolution / 2, shadowMapResolution));
|
||||
|
||||
texRegions.push_back(LifeMath::float4(0.5f, 0.5f, 0.5f, 0.5f));
|
||||
viewRegions.push_back(LifeMath::Rect2i(shadowMapResolution / 2, shadowMapResolution / 2, shadowMapResolution, shadowMapResolution));
|
||||
break;
|
||||
case 4:
|
||||
texRegions.push_back(LifeMath::float4(0.0f, 0.0f, 0.5f, 0.5f));
|
||||
viewRegions.push_back(LifeMath::Rect2i(0, 0, shadowMapResolution / 2, shadowMapResolution / 2));
|
||||
|
||||
texRegions.push_back(LifeMath::float4(0.5f, 0.0f, 0.5f, 0.5f));
|
||||
viewRegions.push_back(LifeMath::Rect2i(shadowMapResolution / 2, 0, shadowMapResolution / 2, shadowMapResolution / 2));
|
||||
|
||||
texRegions.push_back(LifeMath::float4(0.0f, 0.5f, 0.5f, 0.5f));
|
||||
viewRegions.push_back(LifeMath::Rect2i(0, shadowMapResolution / 2, shadowMapResolution / 2, shadowMapResolution / 2));
|
||||
|
||||
texRegions.push_back(LifeMath::float4(0.5f, 0.5f, 0.5f, 0.5f));
|
||||
viewRegions.push_back(LifeMath::Rect2i(shadowMapResolution / 2, shadowMapResolution / 2, shadowMapResolution / 2, shadowMapResolution / 2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
public:
|
||||
IDepthStencilState* depthState;
|
||||
IShader* rtdPs;
|
||||
IShader* rtdPsAT;
|
||||
IShader* rtdCubePs;
|
||||
IShader* rtdCubePsAT;
|
||||
ITextureSampler* samplerPCF;
|
||||
ShadowMapManager()
|
||||
:shadowMapResolution(1024)
|
||||
{
|
||||
for(int i = 0; i<4; i++)
|
||||
{
|
||||
texRegions.push_back(LifeMath::float4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
~ShadowMapManager()
|
||||
{
|
||||
SAFE_DELETE(depthBuffer);
|
||||
SAFE_DELETE(rtdPs);
|
||||
SAFE_DELETE(shadowBlendState);
|
||||
SAFE_DELETE(depthState);
|
||||
}
|
||||
SHADOW_DATA getShadowInfo(int id)
|
||||
{
|
||||
SHADOW_DATA data;
|
||||
data.uvOffset_uvScale = texRegions[id];
|
||||
data.shadowMapTexelSize_dummy.X = (float)shadowMapResolution;
|
||||
data.shadowMapTexelSize_dummy.Y = (float)shadowMapResolution;
|
||||
return data;
|
||||
}
|
||||
void beginShadowRendering(int lightCount)
|
||||
{
|
||||
renderer->SetScissorRectangle(LifeMath::Rect2i(0, 0, shadowMapResolution, shadowMapResolution));
|
||||
curLightIndex = 0;
|
||||
if (lightCount > 0)
|
||||
{
|
||||
if (lightCount > 4)
|
||||
lightCount = 4;
|
||||
ComputeDepthRegionDistribution(lightCount);
|
||||
}
|
||||
renderer->UnbindResourcesPS();
|
||||
|
||||
renderer->SetTargets(shadowBuffer, depthBuffer);
|
||||
LifeMath::float4 color = LifeMath::float4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
renderer->ClearDepthStencil(depthBuffer, 1.0f, 0);
|
||||
//renderer->ClearBuffers(CF_DEPTH_BUFFER, 0x00000000, 1.0f, 0);
|
||||
// renderer->ClearRenderTarget(shadowBuffer, &color);
|
||||
//renderer->SetBlendState(shadowBlendState);
|
||||
|
||||
renderer->SetDepthStencilState(depthState);
|
||||
renderer->SetPSTextureSampler(samplerPCF, 2);
|
||||
//renderer->SetPixelShader(rtdPs);
|
||||
}
|
||||
|
||||
void beginLightRender(Light* light)
|
||||
{
|
||||
lightMatrices[curLightIndex] = light->getMatrix();
|
||||
|
||||
// renderer->ClearBuffers(CF_DEPTH_BUFFER, 0x00000000, 1.0f, 0);
|
||||
renderer->SetViewport(viewRegions[curLightIndex]);
|
||||
|
||||
//renderer->SetViewport(viewRegions[curLightIndex], 0, 100000000.0f);
|
||||
}
|
||||
void endLightRender()
|
||||
{
|
||||
curLightIndex++;
|
||||
}
|
||||
|
||||
ITexture2D* getShadowMap()
|
||||
{
|
||||
return shadowBuffer;
|
||||
}
|
||||
|
||||
void Init(IRenderer* _renderer)
|
||||
{
|
||||
renderer = _renderer;
|
||||
|
||||
#define MAX_LINEAR_DEPTH 1.e30f
|
||||
/* ComparisonFunc = LESS;
|
||||
Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
|
||||
AddressU = Border;
|
||||
AddressV = Border;
|
||||
BorderColor = float4(MAX_LINEAR_DEPTH, 0, 0, 0);*/
|
||||
|
||||
ISamplerDescription desc(Border, Border, Border, ComparisonMinMagLinearMipPoint, COMPARISON_LESS);
|
||||
samplerPCF = renderer->CreateTextureSampler(&desc);
|
||||
|
||||
depthBuffer = CG::me()->GetRenderer()->CreateDepthTarget(shadowMapResolution, shadowMapResolution, FORMAT_R32_TYPELESS);
|
||||
|
||||
shadowBuffer = CG::me()->GetRenderer()->CreateRenderTarget(shadowMapResolution, shadowMapResolution, FORMAT_R32_FLOAT);
|
||||
|
||||
rtdPs = ResourceManager::me()->CompileUserShaderPS(String(_text("RTD_PCF.psh")));
|
||||
rtdPsAT = ResourceManager::me()->CompileUserShaderPS(String(_text("RTD_PCF_AT.psh")));
|
||||
|
||||
rtdCubePs = ResourceManager::me()->CompileUserShaderPS(String(_text("RTD_PCF_CUBE.psh")));
|
||||
rtdCubePsAT = ResourceManager::me()->CompileUserShaderPS(String(_text("RTD_PCF_AT.psh")));
|
||||
|
||||
shadowBlendState = CG::me()->GetRenderer()->CreateBlendState(false, false, BLEND_OP_ADD, BLEND_ZERO, BLEND_ONE, 0);
|
||||
|
||||
restoreBlendState = CG::me()->GetRenderer()->CreateBlendState(true, false, BLEND_OP_ADD, BLEND_ONE, BLEND_ZERO, 1 | 2 | 4 | 8);
|
||||
|
||||
depthState = renderer->CreateDSState(true, true, COMPARISON_LESS);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif // ShadowMapManager_h__
|
||||
Reference in New Issue
Block a user