diff --git a/trinity/Interior/Tr2InteriorScene.cpp b/trinity/Interior/Tr2InteriorScene.cpp index 31eec69c4..1236b147b 100644 --- a/trinity/Interior/Tr2InteriorScene.cpp +++ b/trinity/Interior/Tr2InteriorScene.cpp @@ -137,6 +137,7 @@ Tr2InteriorScene::Tr2InteriorScene( IRoot* lockobj /*= NULL */ ) : m_optimizeShadows( true ), m_renderShadows( true ), m_debugRenderShadowMaps( false ), + m_shadowMapsDirty( true ), m_shadowMap0Var( "SpotlightShadow0", (TriTextureRes*)NULL ), m_shadowMap1Var( "SpotlightShadow1", (TriTextureRes*)NULL ), m_shadowMap2Var( "SpotlightShadow2", (TriTextureRes*)NULL ), @@ -212,14 +213,9 @@ bool Tr2InteriorScene::OnModified( Be::Var* value ) SetBackgroundCubemapResPath(); } - if( IsMatch( value, m_shadowSize ) ) + if( IsMatch( value, m_shadowSize ) || IsMatch( value, m_shadowCount ) ) { - SetupShadowMaps(); - } - - if( IsMatch( value, m_shadowCount ) ) - { - SetupShadowMaps(); + m_shadowMapsDirty = true; } return true; @@ -230,7 +226,7 @@ void Tr2InteriorScene::OnListModified( long event, ssize_t key, ssize_t key2, IR { if( theList == &m_lights ) { - SetupShadowMaps(); + m_shadowMapsDirty = true; } else if( theList == &m_dynamics ) @@ -659,21 +655,49 @@ void Tr2InteriorScene::RenderFullForward( Tr2RenderContext& renderContext ) void Tr2InteriorScene::SetupShadowMaps() { - m_lightRenderTargets.Clear(); + m_shadowMapsDirty = false; - for( int i = 0; i < (int)( m_lights.size() ) && i < m_shadowCount; i++ ) + const unsigned size = m_shadowSize > 0 ? (unsigned)m_shadowSize : 1; + int count = (int)m_lights.size(); + if( count > m_shadowCount ) + { + count = m_shadowCount; + } + if( count < 0 ) + { + count = 0; + } + + if( m_lightDepthStencil && ( !m_lightDepthStencil->IsValid() || m_lightDepthStencil->GetWidth() != size ) ) + { + m_lightDepthStencil = Tr2DepthStencilPtr(); + } + if( !m_lightDepthStencil ) + { + m_lightDepthStencil.CreateInstance(); + m_lightDepthStencil->Create( size, size, Tr2RenderContextEnum::DSFMT_D32, 0, 0 ); + } + + if( !m_lightRenderTargets.empty() ) + { + Tr2RenderTarget* first = m_lightRenderTargets[0]; + if( !first || !first->IsValid() || first->GetWidth() != size ) + { + m_lightRenderTargets.Clear(); + } + } + while( (int)m_lightRenderTargets.size() > count ) + { + m_lightRenderTargets.Remove( -1 ); + } + while( (int)m_lightRenderTargets.size() < count ) { Tr2RenderTargetPtr rt; rt.CreateInstance(); rt->SetName( "ShadowMap" ); - rt->Create( m_shadowSize, m_shadowSize, 1, Tr2RenderContextEnum::PIXEL_FORMAT_R32_FLOAT, 1, 0 ); + rt->Create( size, size, 1, Tr2RenderContextEnum::PIXEL_FORMAT_R32_FLOAT, 1, 0 ); m_lightRenderTargets.Append( rt ); } - - // Setup depth stencil texture - m_lightDepthStencil = Tr2DepthStencilPtr(); - m_lightDepthStencil.CreateInstance(); - m_lightDepthStencil->Create( m_shadowSize, m_shadowSize, Tr2RenderContextEnum::DSFMT_D32, 0, 0 ); } // -------------------------------------------------------------------------------------- @@ -689,7 +713,7 @@ void Tr2InteriorScene::RenderShadows( Tr2RenderContext& renderContext ) return; } - if( !m_lightDepthStencil ) + if( m_shadowMapsDirty || !m_lightDepthStencil ) { SetupShadowMaps(); } @@ -926,7 +950,7 @@ void Tr2InteriorScene::AddLightSource( ITr2InteriorLight* lightSource ) m_lights.Insert( -1, lightSource ); } - SetupShadowMaps(); + m_shadowMapsDirty = true; } // -------------------------------------------------------------------------------------- @@ -956,7 +980,7 @@ void Tr2InteriorScene::RemoveLightSource( ITr2InteriorLight* lightSource ) m_lights.Remove( pos ); - SetupShadowMaps(); + m_shadowMapsDirty = true; } // -------------------------------------------------------------------------------------- diff --git a/trinity/Interior/Tr2InteriorScene.h b/trinity/Interior/Tr2InteriorScene.h index 0e29e2bfa..dcae56bce 100644 --- a/trinity/Interior/Tr2InteriorScene.h +++ b/trinity/Interior/Tr2InteriorScene.h @@ -155,6 +155,7 @@ class Tr2InteriorScene : public IInitialize, private: // A shared depth stencil texture for light shadow maps Tr2DepthStencilPtr m_lightDepthStencil; + bool m_shadowMapsDirty; // Holds the main render batch list for opaques, decals, and transparent batches ITriRenderBatchAccumulator* m_primaryRenderBatches;