Files
LifeProject/LifeGraphics/ShadowMapManager.h
T

206 lines
6.8 KiB
C++
Raw Normal View History

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