Skip to content

Commit 9057eeb

Browse files
committed
Fix bug where flat overlays wrote to the depth buffer
1 parent f67138f commit 9057eeb

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

src/TSMapEditor/Rendering/MapView.cs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)