Check available texture units in shadow mapping settings

master
krzys-h 2015-08-06 13:47:42 +02:00
parent 4faeffa77d
commit b20d589c87
3 changed files with 93 additions and 93 deletions

View File

@ -2908,9 +2908,14 @@ int CEngine::GetTextureAnisotropyLevel()
return m_textureAnisotropy; return m_textureAnisotropy;
} }
bool CEngine::IsShadowMappingSupported()
{
return m_device->IsShadowMappingSupported() && m_device->GetMaxTextureStageCount() >= 3;
}
void CEngine::SetShadowMapping(bool value) void CEngine::SetShadowMapping(bool value)
{ {
if(!m_device->IsShadowMappingSupported()) value = false; if(!IsShadowMappingSupported()) value = false;
if(value == m_shadowMapping) return; if(value == m_shadowMapping) return;
m_shadowMapping = value; m_shadowMapping = value;
if(!value) if(!value)
@ -2962,8 +2967,14 @@ int CEngine::GetShadowMappingOffscreenResolution()
return m_offscreenShadowRenderingResolution; return m_offscreenShadowRenderingResolution;
} }
bool CEngine::IsShadowMappingQualitySupported()
{
return IsShadowMappingSupported() && m_device->GetMaxTextureStageCount() >= 6;
}
void CEngine::SetShadowMappingQuality(bool value) void CEngine::SetShadowMappingQuality(bool value)
{ {
if(!IsShadowMappingQualitySupported()) value = false;
m_qualityShadows = value; m_qualityShadows = value;
} }
@ -3445,14 +3456,6 @@ void CEngine::RenderShadowMap()
if (!m_shadowMapping) return; if (!m_shadowMapping) return;
if (m_device->GetMaxTextureStageCount() < 3)
{
m_shadowMapping = false;
GetLogger()->Error("Cannot use shadow maps, not enough texture units\n");
GetLogger()->Error("Disabling shadow mapping\n");
return;
}
m_app->StartPerformanceCounter(PCNT_RENDER_SHADOW_MAP); m_app->StartPerformanceCounter(PCNT_RENDER_SHADOW_MAP);
// If no shadow map texture exists, create it // If no shadow map texture exists, create it
@ -3637,94 +3640,85 @@ void CEngine::UseShadowMapping(bool enable)
if (m_qualityShadows) if (m_qualityShadows)
{ {
if (m_device->GetMaxTextureStageCount() < 6) // Texture Unit 2
m_device->SetTextureEnabled(2, true);
m_device->SetTexture(2, m_shadowMap);
m_device->SetTransform(TRANSFORM_SHADOW, m_shadowTextureMat);
Math::Matrix identity;
identity.LoadIdentity();
m_device->SetTransform(TRANSFORM_WORLD, identity);
float shadowBias = 0.6f;
float shadowUnbias = 1.0f - shadowBias;
TextureStageParams params;
params.colorOperation = TEX_MIX_OPER_MODULATE;
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
params.colorArg2 = TEX_MIX_ARG_FACTOR;
params.colorOperation = TEX_MIX_OPER_DEFAULT;
params.factor = Color(shadowBias, shadowBias, shadowBias, 1.0f);
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
m_device->SetTextureStageParams(2, params);
TextureGenerationParams genParams;
for (int i = 0; i < 4; i++)
{ {
m_qualityShadows = false; genParams.coords[i].mode = TEX_GEN_EYE_LINEAR;
GetLogger()->Error("Cannot use quality shadow maps, not enough texture units\n");
GetLogger()->Error("Attempting to use lower quality shadow maps\n");
}
else
{
// Texture Unit 2
m_device->SetTextureEnabled(2, true);
m_device->SetTexture(2, m_shadowMap);
m_device->SetTransform(TRANSFORM_SHADOW, m_shadowTextureMat);
Math::Matrix identity; for (int j = 0; j < 4; j++)
identity.LoadIdentity();
m_device->SetTransform(TRANSFORM_WORLD, identity);
float shadowBias = 0.6f;
float shadowUnbias = 1.0f - shadowBias;
TextureStageParams params;
params.colorOperation = TEX_MIX_OPER_MODULATE;
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
params.colorArg2 = TEX_MIX_ARG_FACTOR;
params.colorOperation = TEX_MIX_OPER_DEFAULT;
params.factor = Color(shadowBias, shadowBias, shadowBias, 1.0f);
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
m_device->SetTextureStageParams(2, params);
TextureGenerationParams genParams;
for (int i = 0; i < 4; i++)
{ {
genParams.coords[i].mode = TEX_GEN_EYE_LINEAR; genParams.coords[i].plane[j] = (i == j ? 1.0f : 0.0f);
for (int j = 0; j < 4; j++)
{
genParams.coords[i].plane[j] = (i == j ? 1.0f : 0.0f);
}
} }
m_device->SetTextureCoordGeneration(2, genParams);
// Texture Unit 3
m_device->SetTextureEnabled(3, true);
m_device->SetTexture(3, m_shadowMap);
params.LoadDefault();
params.colorOperation = TEX_MIX_OPER_ADD;
params.colorArg1 = TEX_MIX_ARG_COMPUTED_COLOR;
params.colorArg2 = TEX_MIX_ARG_FACTOR;
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
params.factor = Color(shadowUnbias, shadowUnbias, shadowUnbias, 0.0f);
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
m_device->SetTextureStageParams(3, params);
// Texture Unit 4
m_device->SetTextureEnabled(4, true);
m_device->SetTexture(4, m_shadowMap);
params.LoadDefault();
params.colorOperation = TEX_MIX_OPER_MODULATE;
params.colorArg1 = TEX_MIX_ARG_COMPUTED_COLOR;
params.colorArg2 = TEX_MIX_ARG_SRC_COLOR;
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
m_device->SetTextureStageParams(4, params);
// Texture Unit 5
m_device->SetTextureEnabled(5, true);
m_device->SetTexture(5, m_shadowMap);
params.LoadDefault();
params.colorOperation = TEX_MIX_OPER_MODULATE;
params.colorArg1 = TEX_MIX_ARG_COMPUTED_COLOR;
params.colorArg2 = TEX_MIX_ARG_TEXTURE_0;
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
m_device->SetTextureStageParams(5, params);
} }
m_device->SetTextureCoordGeneration(2, genParams);
// Texture Unit 3
m_device->SetTextureEnabled(3, true);
m_device->SetTexture(3, m_shadowMap);
params.LoadDefault();
params.colorOperation = TEX_MIX_OPER_ADD;
params.colorArg1 = TEX_MIX_ARG_COMPUTED_COLOR;
params.colorArg2 = TEX_MIX_ARG_FACTOR;
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
params.factor = Color(shadowUnbias, shadowUnbias, shadowUnbias, 0.0f);
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
m_device->SetTextureStageParams(3, params);
// Texture Unit 4
m_device->SetTextureEnabled(4, true);
m_device->SetTexture(4, m_shadowMap);
params.LoadDefault();
params.colorOperation = TEX_MIX_OPER_MODULATE;
params.colorArg1 = TEX_MIX_ARG_COMPUTED_COLOR;
params.colorArg2 = TEX_MIX_ARG_SRC_COLOR;
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
m_device->SetTextureStageParams(4, params);
// Texture Unit 5
m_device->SetTextureEnabled(5, true);
m_device->SetTexture(5, m_shadowMap);
params.LoadDefault();
params.colorOperation = TEX_MIX_OPER_MODULATE;
params.colorArg1 = TEX_MIX_ARG_COMPUTED_COLOR;
params.colorArg2 = TEX_MIX_ARG_TEXTURE_0;
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
m_device->SetTextureStageParams(5, params);
} }
else // Simpler shadows else // Simpler shadows
{ {

View File

@ -1087,12 +1087,14 @@ public:
//@{ //@{
//! Management of shadow mapping //! Management of shadow mapping
bool IsShadowMappingSupported();
void SetShadowMapping(bool value); void SetShadowMapping(bool value);
bool GetShadowMapping(); bool GetShadowMapping();
void SetShadowMappingOffscreen(bool value); void SetShadowMappingOffscreen(bool value);
bool GetShadowMappingOffscreen(); bool GetShadowMappingOffscreen();
void SetShadowMappingOffscreenResolution(int resolution); void SetShadowMappingOffscreenResolution(int resolution);
int GetShadowMappingOffscreenResolution(); int GetShadowMappingOffscreenResolution();
bool IsShadowMappingQualitySupported();
void SetShadowMappingQuality(bool value); void SetShadowMappingQuality(bool value);
bool GetShadowMappingQuality(); bool GetShadowMappingQuality();
//@} //@}

View File

@ -253,7 +253,7 @@ void CScreenSetupGraphics::CreateInterface()
shadowOptions[0] = "Screen buffer"; // TODO: Is this the proper name for this? shadowOptions[0] = "Screen buffer"; // TODO: Is this the proper name for this?
} }
pes->SetPossibleValues(shadowOptions); pes->SetPossibleValues(shadowOptions);
if (!m_engine->GetDevice()->IsShadowMappingSupported()) if (!m_engine->IsShadowMappingSupported())
{ {
pes->ClearState(STATE_ENABLE); pes->ClearState(STATE_ENABLE);
} }
@ -270,6 +270,10 @@ void CScreenSetupGraphics::CreateInterface()
ddim.y = dim.y*0.5f; ddim.y = dim.y*0.5f;
pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SHADOW_MAPPING_QUALITY); pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SHADOW_MAPPING_QUALITY);
pc->SetState(STATE_SHADOW); pc->SetState(STATE_SHADOW);
if (!m_engine->IsShadowMappingQualitySupported())
{
pes->ClearState(STATE_ENABLE);
}
ddim.x = dim.x*2; ddim.x = dim.x*2;
ddim.y = dim.y*1; ddim.y = dim.y*1;