Merge pull request #7288 from RoosterDragon/faster-depth-sorting

Speed up depth sorting of renderables.
This commit is contained in:
Chris Forbes
2015-01-08 14:22:20 +13:00
3 changed files with 11 additions and 21 deletions

View File

@@ -14,22 +14,6 @@ using System.Linq;
namespace OpenRA.Graphics namespace OpenRA.Graphics
{ {
public class RenderableComparer : IComparer<IRenderable>
{
WorldRenderer wr;
public RenderableComparer(WorldRenderer wr)
{
this.wr = wr;
}
public int Compare(IRenderable x, IRenderable y)
{
var xOrder = wr.ScreenZPosition(x.Pos, x.ZOffset);
var yOrder = wr.ScreenZPosition(y.Pos, y.ZOffset);
return xOrder.CompareTo(yOrder);
}
}
public interface IRenderable public interface IRenderable
{ {
WPos Pos { get; } WPos Pos { get; }

View File

@@ -31,6 +31,9 @@ namespace OpenRA.Graphics
public sealed class WorldRenderer : IDisposable public sealed class WorldRenderer : IDisposable
{ {
public static readonly Func<IRenderable, int> RenderableScreenZPositionComparisonKey =
r => ZPosition(r.Pos, r.ZOffset);
public readonly World World; public readonly World World;
public readonly Theater Theater; public readonly Theater Theater;
public Viewport Viewport { get; private set; } public Viewport Viewport { get; private set; }
@@ -69,7 +72,6 @@ namespace OpenRA.Graphics
List<IRenderable> GenerateRenderables() List<IRenderable> GenerateRenderables()
{ {
var comparer = new RenderableComparer(this);
var actors = World.ScreenMap.ActorsInBox(Viewport.TopLeft, Viewport.BottomRight) var actors = World.ScreenMap.ActorsInBox(Viewport.TopLeft, Viewport.BottomRight)
.Append(World.WorldActor) .Append(World.WorldActor)
.ToList(); .ToList();
@@ -82,7 +84,7 @@ namespace OpenRA.Graphics
if (World.OrderGenerator != null) if (World.OrderGenerator != null)
worldRenderables = worldRenderables.Concat(World.OrderGenerator.Render(this, World)); worldRenderables = worldRenderables.Concat(World.OrderGenerator.Render(this, World));
worldRenderables = worldRenderables.OrderBy(r => r, comparer); worldRenderables = worldRenderables.OrderBy(RenderableScreenZPositionComparisonKey);
// Effects are drawn on top of all actors // Effects are drawn on top of all actors
// HACK: Effects aren't interleaved with actors. // HACK: Effects aren't interleaved with actors.
@@ -241,7 +243,12 @@ namespace OpenRA.Graphics
public float ScreenZPosition(WPos pos, int offset) public float ScreenZPosition(WPos pos, int offset)
{ {
var ts = Game.ModData.Manifest.TileSize; var ts = Game.ModData.Manifest.TileSize;
return (pos.Y + pos.Z + offset) * ts.Height / 1024f; return ZPosition(pos, offset) * ts.Height / 1024f;
}
static int ZPosition(WPos pos, int offset)
{
return pos.Y + pos.Z + offset;
} }
public WPos Position(int2 screenPx) public WPos Position(int2 screenPx)

View File

@@ -127,11 +127,10 @@ namespace OpenRA.Mods.RA.Orders
initialized = true; initialized = true;
} }
var comparer = new RenderableComparer(wr);
var offset = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, buildingInfo); var offset = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, buildingInfo);
var previewRenderables = preview var previewRenderables = preview
.SelectMany(p => p.Render(wr, offset)) .SelectMany(p => p.Render(wr, offset))
.OrderBy(r => r, comparer); .OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey);
foreach (var r in previewRenderables) foreach (var r in previewRenderables)
yield return r; yield return r;