@@ -158,9 +158,10 @@ public MapView(WindowManager windowManager, Map map, TheaterGraphics theaterGrap
158158 private Rectangle mapRenderSourceRectangle ;
159159 private Rectangle mapRenderDestinationRectangle ;
160160
161- private DepthStencilState depthRenderStencilState ;
162- private DepthStencilState objectRenderStencilState ;
163- private DepthStencilState shadowRenderStencilState ;
161+ private DepthStencilState depthRenderStencilState ; // Depth stencil state for rendering terrain. Reads and writes depth information.
162+ private DepthStencilState depthReadStencilState ; // Depth stencil state for rendering smudges and flat overlays. Reads depth information, but does not write it.
163+ private DepthStencilState objectRenderStencilState ; // Depth stencil state for rendering objects. Reads and writes depth information. Also writes stencil information for shadow rendering.
164+ private DepthStencilState shadowRenderStencilState ; // Depth stencil state for rendering shadows. Reads depth information. Also reads stencil information to avoid shadowing objects (the C&C engine does allow shadows on objects either).
164165
165166 public void AddRefreshPoint ( Point2D point , int size = 1 )
166167 {
@@ -313,6 +314,16 @@ private void CreateDepthStencilStates()
313314 } ;
314315 }
315316
317+ if ( depthReadStencilState == null )
318+ {
319+ depthReadStencilState = new DepthStencilState ( )
320+ {
321+ DepthBufferEnable = true ,
322+ DepthBufferWriteEnable = false ,
323+ DepthBufferFunction = CompareFunction . GreaterEqual ,
324+ } ;
325+ }
326+
316327 // Depth stencil state for rendering objects.
317328 // Sets the stencil value in the stencil buffer to prevent shadows from being drawn over objects.
318329 // While it'd usually look nicer, shadows cannot be cast over objects in the C&C engine.
@@ -408,7 +419,7 @@ public void DrawVisibleMapPortion()
408419 // At this point of drawing, depth testing is done on depth buffer embedded in the main map render target.
409420 Renderer . PopRenderTarget ( ) ;
410421
411- var palettedTerrainDrawSettings = new SpriteBatchSettings ( SpriteSortMode . Deferred , BlendState . Opaque , null , depthRenderStencilState , null , palettedTerrainDrawEffect ) ;
422+ var palettedTerrainDrawSettings = new SpriteBatchSettings ( SpriteSortMode . Deferred , BlendState . Opaque , null , depthReadStencilState , null , palettedTerrainDrawEffect ) ;
412423 Renderer . PushRenderTarget ( mapRenderTarget , palettedTerrainDrawSettings ) ;
413424
414425 // Smudges can be drawn as part of regular terrain.
@@ -418,14 +429,14 @@ public void DrawVisibleMapPortion()
418429
419430 // Flat overlays can also be drawn as part of regular terrain, but they need to use the more complex shader.
420431 SetPaletteEffectParams ( palettedColorDrawEffect , TheaterGraphics . TheaterPalette . GetTexture ( ) , true , false , false ) ;
421- var palettedColorDrawSettings = new SpriteBatchSettings ( SpriteSortMode . Deferred , BlendState . Opaque , null , depthRenderStencilState , null , palettedColorDrawEffect ) ;
432+ var palettedColorDrawSettings = new SpriteBatchSettings ( SpriteSortMode . Deferred , BlendState . Opaque , null , depthReadStencilState , null , palettedColorDrawEffect ) ;
422433 Renderer . PushSettings ( palettedColorDrawSettings ) ;
423434 DrawFlatOverlays ( ) ;
424435
425436 Renderer . PopRenderTarget ( ) ;
426437
427438 // Render non-flat objects
428- Renderer . PushRenderTarget ( mapRenderTarget ) ;
439+ Renderer . PushRenderTarget ( mapRenderTarget , new SpriteBatchSettings ( SpriteSortMode . Deferred , BlendState . AlphaBlend , null , objectRenderStencilState , null , palettedColorDrawEffect ) ) ;
429440
430441 DrawBuildings ( ) ;
431442 DrawGameObjects ( ) ;
@@ -940,7 +951,7 @@ private void DrawFlatOverlays()
940951 objectSpriteRecord . ProcessedObjects . Add ( flatOverlaysToRender [ i ] ) ;
941952 }
942953
943- ProcessObjectSpriteRecord ( false , false , true ) ; // Do not process building shadows yet, let DrawGameObjects do it
954+ ProcessObjectSpriteRecord ( true , false , true ) ; // Flat overlays do not render to the depth buffer
944955 objectSpriteRecord . Clear ( true ) ;
945956 }
946957
@@ -958,7 +969,7 @@ private void DrawBuildings()
958969 objectSpriteRecord . ProcessedObjects . Add ( structuresToRender [ i ] ) ;
959970 }
960971
961- ProcessObjectSpriteRecord ( true , false , false ) ; // Do not process building shadows yet, let DrawGameObjects do it
972+ ProcessObjectSpriteRecord ( false , false , false ) ; // Do not process building shadows yet, let DrawGameObjects do it
962973 objectSpriteRecord . Clear ( true ) ;
963974 }
964975
@@ -1015,12 +1026,12 @@ private void DrawObject(GameObject gameObject)
10151026 }
10161027 }
10171028
1018- private void ProcessObjectSpriteRecord ( bool complexDepth , bool processShadows , bool alphaBlendNonPalettedSprites )
1029+ private void ProcessObjectSpriteRecord ( bool noDepthWriting , bool processShadows , bool alphaBlendNonPalettedSprites )
10191030 {
10201031 if ( objectSpriteRecord . LineEntries . Count > 0 )
10211032 {
10221033 SetPaletteEffectParams ( palettedColorDrawEffect , null , false , false , false ) ;
1023- Renderer . PushSettings ( new SpriteBatchSettings ( SpriteSortMode . Deferred , BlendState . Opaque , null , objectRenderStencilState , null , palettedColorDrawEffect ) ) ;
1034+ Renderer . PushSettings ( new SpriteBatchSettings ( SpriteSortMode . Deferred , BlendState . Opaque , null , noDepthWriting ? depthReadStencilState : objectRenderStencilState , null , palettedColorDrawEffect ) ) ;
10241035
10251036 for ( int i = 0 ; i < objectSpriteRecord . LineEntries . Count ; i ++ )
10261037 {
@@ -1041,7 +1052,7 @@ private void ProcessObjectSpriteRecord(bool complexDepth, bool processShadows, b
10411052 bool isRemap = kvp . Key . Item2 ;
10421053
10431054 SetPaletteEffectParams ( palettedColorDrawEffect , paletteTexture , true , isRemap , false ) ;
1044- gameObjectBatcher . Begin ( palettedColorDrawEffect , objectRenderStencilState ) ;
1055+ gameObjectBatcher . Begin ( palettedColorDrawEffect , noDepthWriting ? depthReadStencilState : objectRenderStencilState ) ;
10451056
10461057 for ( int i = 0 ; i < kvp . Value . Count ; i ++ )
10471058 {
@@ -1056,7 +1067,7 @@ private void ProcessObjectSpriteRecord(bool complexDepth, bool processShadows, b
10561067 if ( objectSpriteRecord . NonPalettedSpriteEntries . Count > 0 )
10571068 {
10581069 SetPaletteEffectParams ( palettedColorDrawEffect , null , false , false , false ) ;
1059- gameObjectBatcher . Begin ( palettedColorDrawEffect , alphaBlendNonPalettedSprites ? depthRenderStencilState : objectRenderStencilState ) ;
1070+ gameObjectBatcher . Begin ( palettedColorDrawEffect , noDepthWriting ? depthReadStencilState : objectRenderStencilState ) ;
10601071
10611072 for ( int i = 0 ; i < objectSpriteRecord . NonPalettedSpriteEntries . Count ; i ++ )
10621073 {
@@ -1070,7 +1081,7 @@ private void ProcessObjectSpriteRecord(bool complexDepth, bool processShadows, b
10701081 if ( processShadows && objectSpriteRecord . ShadowEntries . Count > 0 )
10711082 {
10721083 SetPaletteEffectParams ( palettedColorDrawEffect , null , false , false , true ) ;
1073- gameObjectBatcher . Begin ( palettedColorDrawEffect , shadowRenderStencilState ) ;
1084+ gameObjectBatcher . Begin ( palettedColorDrawEffect , noDepthWriting ? depthReadStencilState : objectRenderStencilState ) ;
10741085 GraphicsDevice . BlendState = BlendState . AlphaBlend ;
10751086
10761087 for ( int i = 0 ; i < objectSpriteRecord . ShadowEntries . Count ; i ++ )
0 commit comments