Fixed possible problems when trying to use shadow maps in unsupported configuraions (#522)

master
krzys-h 2015-07-20 22:34:39 +02:00
parent 52a3e0b24f
commit 72b9738eb9
11 changed files with 120 additions and 4 deletions

View File

@ -444,6 +444,15 @@ public:
//! Returns max samples supported
virtual int GetMaxSamples() = 0;
//! Checks if shadow mapping is supported
virtual bool IsShadowMappingSupported() = 0;
//! Returns max texture size supported
virtual int GetMaxTextureSize() = 0;
//! Checks if framebuffers are supported
virtual bool IsFramebufferSupported() = 0;
};

View File

@ -397,4 +397,19 @@ int CNullDevice::GetMaxSamples()
return 1;
}
bool CNullDevice::IsShadowMappingSupported()
{
return false;
}
int CNullDevice::GetMaxTextureSize()
{
return 0;
}
bool CNullDevice::IsFramebufferSupported()
{
return false;
}
} // namespace Gfx

View File

@ -157,6 +157,12 @@ public:
virtual int GetMaxSamples();
virtual bool IsShadowMappingSupported();
virtual int GetMaxTextureSize();
virtual bool IsFramebufferSupported();
private:
Math::Matrix m_matrix;
Material m_material;

View File

@ -2875,6 +2875,7 @@ int CEngine::GetTextureAnisotropyLevel()
void CEngine::SetShadowMapping(bool value)
{
if(!m_device->IsShadowMappingSupported()) value = false;
if(value == m_shadowMapping) return;
m_shadowMapping = value;
if(!value)
@ -2892,6 +2893,7 @@ bool CEngine::GetShadowMapping()
void CEngine::SetShadowMappingOffscreen(bool value)
{
if(!m_device->IsFramebufferSupported()) value = false;
if(value == m_offscreenShadowRendering) return;
m_offscreenShadowRendering = value;
if(value)
@ -2913,6 +2915,7 @@ bool CEngine::GetShadowMappingOffscreen()
void CEngine::SetShadowMappingOffscreenResolution(int resolution)
{
resolution = Math::Min(resolution, m_device->GetMaxTextureSize());
if(resolution == m_offscreenShadowRenderingResolution) return;
m_offscreenShadowRenderingResolution = resolution;
m_device->DeleteFramebuffer("shadow");
@ -3403,6 +3406,10 @@ void CEngine::RenderShadowMap()
{
if (!m_shadowMapping) return;
m_shadowMapping = m_shadowMapping && m_device->IsShadowMappingSupported();
m_offscreenShadowRendering = m_offscreenShadowRendering && m_device->IsFramebufferSupported();
m_offscreenShadowRenderingResolution = Math::Min(m_offscreenShadowRenderingResolution, m_device->GetMaxTextureSize());
if (m_device->GetMaxTextureStageCount() < 3)
{
m_shadowMapping = false;

View File

@ -1788,4 +1788,21 @@ int CGL21Device::GetMaxSamples()
return m_maxSamples;
}
bool CGL21Device::IsShadowMappingSupported()
{
return true;
}
int CGL21Device::GetMaxTextureSize()
{
int value;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
return value;
}
bool CGL21Device::IsFramebufferSupported()
{
return m_framebufferSupport != FBS_NONE;
}
} // namespace Gfx

View File

@ -152,6 +152,12 @@ public:
virtual int GetMaxSamples() override;
virtual bool IsShadowMappingSupported() override;
virtual int GetMaxTextureSize() override;
virtual bool IsFramebufferSupported() override;
private:
//! Updates position for given light based on transformation matrices
void UpdateLightPosition(int index);

View File

@ -1981,4 +1981,21 @@ int CGL33Device::GetMaxSamples()
return m_maxSamples;
}
bool CGL33Device::IsShadowMappingSupported()
{
return true;
}
int CGL33Device::GetMaxTextureSize()
{
int value;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
return value;
}
bool CGL33Device::IsFramebufferSupported()
{
return true;
}
} // namespace Gfx

View File

@ -151,6 +151,12 @@ public:
virtual int GetMaxSamples() override;
virtual bool IsShadowMappingSupported() override;
virtual int GetMaxTextureSize() override;
virtual bool IsFramebufferSupported() override;
private:
//! Updates position for given light based on transformation matrices
void UpdateLightPosition(int index);

View File

@ -195,7 +195,7 @@ bool CGLDevice::Create()
GetLogger()->Warn("GLEW reports multitexturing not supported - graphics quality will be degraded!\n");
// Detect Shadow mapping support
if (m_glMajor >= 2 || m_glMinor >= 4) // Core depth texture+shadow, OpenGL 1.4+
if (m_glMajor > 1 || m_glMinor >= 4) // Core depth texture+shadow, OpenGL 1.4+
{
m_shadowMappingSupport = SMS_CORE;
GetLogger()->Info("Shadow mapping available (core)\n");
@ -1920,4 +1920,21 @@ int CGLDevice::GetMaxSamples()
return m_maxSamples;
}
bool CGLDevice::IsShadowMappingSupported()
{
return m_shadowMappingSupport != SMS_NONE;
}
int CGLDevice::GetMaxTextureSize()
{
int value;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
return value;
}
bool CGLDevice::IsFramebufferSupported()
{
return m_framebufferSupport != FBS_NONE;
}
} // namespace Gfx

View File

@ -171,6 +171,12 @@ public:
virtual int GetMaxSamples() override;
virtual bool IsShadowMappingSupported() override;
virtual int GetMaxTextureSize() override;
virtual bool IsFramebufferSupported() override;
private:
//! Updates internal modelview matrix
void UpdateModelviewMatrix();

View File

@ -1246,11 +1246,21 @@ void CMainDialog::ChangePhase(Phase phase)
pes->SetState(STATE_SHADOW);
std::map<float, std::string> shadowOptions = {
{ -1, "Disabled" },
//{ 0, "Screen buffer" }, //TODO: Is this needed? Maybe enable only if offscreen rendering not available?
};
for(int i = 128; i <= 4096; i *= 2)
shadowOptions[i] = StrUtils::ToString<int>(i)+"x"+StrUtils::ToString<int>(i);
if (m_engine->GetDevice()->IsFramebufferSupported())
{
for(int i = 128; i <= m_engine->GetDevice()->GetMaxTextureSize(); i *= 2)
shadowOptions[i] = StrUtils::ToString<int>(i)+"x"+StrUtils::ToString<int>(i);
}
else
{
shadowOptions[0] = "Screen buffer"; // TODO: Is this the proper name for this?
}
pes->SetPossibleValues(shadowOptions);
if (!m_engine->GetDevice()->IsShadowMappingSupported())
{
pes->ClearState(STATE_ENABLE);
}
pos.y += ddim.y/2;
pos.x += 0.005f;
ddim.x = 0.40f;