From 7df12cb3e9246135843d2f7a45fc31aa8bd648ba Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 21 Dec 2014 11:38:15 +1300 Subject: [PATCH] Update terrain layer when the terrain data changes. --- OpenRA.Game/Graphics/IGraphicsDevice.cs | 1 + OpenRA.Game/Graphics/TerrainRenderer.cs | 52 ++++++++++++++++------ OpenRA.Renderer.Null/NullGraphicsDevice.cs | 1 + OpenRA.Renderer.Sdl2/VertexBuffer.cs | 7 ++- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/OpenRA.Game/Graphics/IGraphicsDevice.cs b/OpenRA.Game/Graphics/IGraphicsDevice.cs index 2fdafe30d2..5712416f14 100755 --- a/OpenRA.Game/Graphics/IGraphicsDevice.cs +++ b/OpenRA.Game/Graphics/IGraphicsDevice.cs @@ -85,6 +85,7 @@ namespace OpenRA { void Bind(); void SetData(T[] vertices, int length); + void SetData(T[] vertices, int start, int length); } public interface IShader diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index 18e95fd747..ee1fb69dda 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -16,33 +16,59 @@ namespace OpenRA.Graphics sealed class TerrainRenderer : IDisposable { readonly IVertexBuffer vertexBuffer; - readonly World world; + readonly Vertex[] updateCellVertices = new Vertex[4]; + readonly float terrainPaletteIndex; + readonly int rowStride; + + readonly WorldRenderer worldRenderer; + readonly Theater theater; + readonly CellLayer mapTiles; readonly Map map; public TerrainRenderer(World world, WorldRenderer wr) { - this.world = world; - this.map = world.Map; + worldRenderer = wr; + theater = wr.Theater; + map = world.Map; + mapTiles = map.MapTiles.Value; + + terrainPaletteIndex = wr.Palette("terrain").TextureIndex; + rowStride = 4 * map.Bounds.Width; + + var vertices = new Vertex[rowStride * map.Bounds.Height]; + vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length); - var terrainPalette = wr.Palette("terrain").TextureIndex; - var vertices = new Vertex[4 * map.Bounds.Height * map.Bounds.Width]; var nv = 0; - foreach (var cell in map.Cells) { - var tile = wr.Theater.TileSprite(map.MapTiles.Value[cell]); - var pos = wr.ScreenPosition(map.CenterOfCell(cell)) + tile.Offset - 0.5f * tile.Size; - Util.FastCreateQuad(vertices, pos, tile, terrainPalette, nv, tile.Size); + GenerateTileVertices(vertices, nv, cell); nv += 4; } - vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length); vertexBuffer.SetData(vertices, nv); + + map.MapTiles.Value.CellEntryChanged += UpdateCell; + map.MapHeight.Value.CellEntryChanged += UpdateCell; + } + + void GenerateTileVertices(Vertex[] vertices, int offset, CPos cell) + { + var tile = theater.TileSprite(mapTiles[cell]); + var pos = worldRenderer.ScreenPosition(map.CenterOfCell(cell)) + tile.Offset - 0.5f * tile.Size; + Util.FastCreateQuad(vertices, pos, tile, terrainPaletteIndex, offset, tile.Size); + } + + public void UpdateCell(CPos cell) + { + var uv = cell.ToMPos(map.TileShape); + var offset = rowStride * (uv.V - map.Bounds.Top) + 4 * (uv.U - map.Bounds.Left); + + GenerateTileVertices(updateCellVertices, 0, cell); + vertexBuffer.SetData(updateCellVertices, offset, 4); } public void Draw(WorldRenderer wr, Viewport viewport) { - var verticesPerRow = 4 * map.Bounds.Width; var cells = viewport.VisibleCells; // Only draw the rows that are visible. @@ -51,10 +77,10 @@ namespace OpenRA.Graphics var lastRow = cells.BottomRight.ToMPos(map).V - map.Bounds.Top + 1; Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer( - vertexBuffer, verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow), + vertexBuffer, rowStride * firstRow, rowStride * (lastRow - firstRow), PrimitiveType.QuadList, wr.Theater.Sheet); - foreach (var r in world.WorldActor.TraitsImplementing()) + foreach (var r in wr.World.WorldActor.TraitsImplementing()) r.Render(wr); } diff --git a/OpenRA.Renderer.Null/NullGraphicsDevice.cs b/OpenRA.Renderer.Null/NullGraphicsDevice.cs index c69b7bf36e..98c05946e3 100644 --- a/OpenRA.Renderer.Null/NullGraphicsDevice.cs +++ b/OpenRA.Renderer.Null/NullGraphicsDevice.cs @@ -104,6 +104,7 @@ namespace OpenRA.Renderer.Null { public void Bind() { } public void SetData(T[] vertices, int length) { } + public void SetData(T[] vertices, int start, int length) { } public void Dispose() { } } } diff --git a/OpenRA.Renderer.Sdl2/VertexBuffer.cs b/OpenRA.Renderer.Sdl2/VertexBuffer.cs index 31feca6405..5ecd000b83 100644 --- a/OpenRA.Renderer.Sdl2/VertexBuffer.cs +++ b/OpenRA.Renderer.Sdl2/VertexBuffer.cs @@ -34,10 +34,15 @@ namespace OpenRA.Renderer.Sdl2 } public void SetData(T[] data, int length) + { + SetData(data, 0, length); + } + + public void SetData(T[] data, int start, int length) { Bind(); GL.BufferSubData(BufferTarget.ArrayBuffer, - IntPtr.Zero, + new IntPtr(VertexSize * start), new IntPtr(VertexSize * length), data); ErrorHandler.CheckGlError();