Skip to content

Commit

Permalink
Use tie breaks for sort order in WorldRenderer.GenerateRenderables
Browse files Browse the repository at this point in the history
  • Loading branch information
RoosterDragon authored and pchote committed Nov 1, 2020
1 parent 13596c1 commit 4daa519
Showing 1 changed file with 20 additions and 1 deletion.
21 changes: 20 additions & 1 deletion OpenRA.Game/Graphics/WorldRenderer.cs
Expand Up @@ -133,7 +133,26 @@ void GenerateRenderables()
foreach (var e in World.ScreenMap.RenderableEffectsInBox(Viewport.TopLeft, Viewport.BottomRight))
renderablesBuffer.AddRange(e.Render(this));

renderablesBuffer.Sort((x, y) => RenderableZPositionComparisonKey(x).CompareTo(RenderableZPositionComparisonKey(y)));
renderablesBuffer.Sort((a, b) =>
{
// Sort is an unstable sort, so elements with the same Z position may get sorted differently each frame.
// This leads to flickering when rendering several frames as the elements get swapped at random.
// To combat this, use a series of arbitrary tie-breaks to determine the "top-most" element.
// This ensures a consistent decision for which one is on top, preventing flicker.
var compared = RenderableZPositionComparisonKey(a).CompareTo(RenderableZPositionComparisonKey(b));
if (compared != 0)
return compared;
compared = a.Pos.X.CompareTo(b.Pos.X);
if (compared != 0)
return compared;
compared = a.Pos.Y.CompareTo(b.Pos.Y);
if (compared != 0)
return compared;
return a.Pos.Z.CompareTo(b.Pos.Z);
});

foreach (var renderable in renderablesBuffer)
preparedRenderables.Add(renderable.PrepareRender(this));
Expand Down

0 comments on commit 4daa519

Please sign in to comment.