Update terrain layer when the terrain data changes.

This commit is contained in:
Paul Chote
2014-12-21 11:38:15 +13:00
parent a48a878a71
commit 7df12cb3e9
4 changed files with 47 additions and 14 deletions

View File

@@ -85,6 +85,7 @@ namespace OpenRA
{ {
void Bind(); void Bind();
void SetData(T[] vertices, int length); void SetData(T[] vertices, int length);
void SetData(T[] vertices, int start, int length);
} }
public interface IShader public interface IShader

View File

@@ -16,33 +16,59 @@ namespace OpenRA.Graphics
sealed class TerrainRenderer : IDisposable sealed class TerrainRenderer : IDisposable
{ {
readonly IVertexBuffer<Vertex> vertexBuffer; readonly IVertexBuffer<Vertex> vertexBuffer;
readonly World world; readonly Vertex[] updateCellVertices = new Vertex[4];
readonly float terrainPaletteIndex;
readonly int rowStride;
readonly WorldRenderer worldRenderer;
readonly Theater theater;
readonly CellLayer<TerrainTile> mapTiles;
readonly Map map; readonly Map map;
public TerrainRenderer(World world, WorldRenderer wr) public TerrainRenderer(World world, WorldRenderer wr)
{ {
this.world = world; worldRenderer = wr;
this.map = world.Map; 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; var nv = 0;
foreach (var cell in map.Cells) foreach (var cell in map.Cells)
{ {
var tile = wr.Theater.TileSprite(map.MapTiles.Value[cell]); GenerateTileVertices(vertices, nv, cell);
var pos = wr.ScreenPosition(map.CenterOfCell(cell)) + tile.Offset - 0.5f * tile.Size;
Util.FastCreateQuad(vertices, pos, tile, terrainPalette, nv, tile.Size);
nv += 4; nv += 4;
} }
vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length);
vertexBuffer.SetData(vertices, nv); 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) public void Draw(WorldRenderer wr, Viewport viewport)
{ {
var verticesPerRow = 4 * map.Bounds.Width;
var cells = viewport.VisibleCells; var cells = viewport.VisibleCells;
// Only draw the rows that are visible. // 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; var lastRow = cells.BottomRight.ToMPos(map).V - map.Bounds.Top + 1;
Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer( Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer(
vertexBuffer, verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow), vertexBuffer, rowStride * firstRow, rowStride * (lastRow - firstRow),
PrimitiveType.QuadList, wr.Theater.Sheet); PrimitiveType.QuadList, wr.Theater.Sheet);
foreach (var r in world.WorldActor.TraitsImplementing<IRenderOverlay>()) foreach (var r in wr.World.WorldActor.TraitsImplementing<IRenderOverlay>())
r.Render(wr); r.Render(wr);
} }

View File

@@ -104,6 +104,7 @@ namespace OpenRA.Renderer.Null
{ {
public void Bind() { } public void Bind() { }
public void SetData(T[] vertices, int length) { } public void SetData(T[] vertices, int length) { }
public void SetData(T[] vertices, int start, int length) { }
public void Dispose() { } public void Dispose() { }
} }
} }

View File

@@ -34,10 +34,15 @@ namespace OpenRA.Renderer.Sdl2
} }
public void SetData(T[] data, int length) public void SetData(T[] data, int length)
{
SetData(data, 0, length);
}
public void SetData(T[] data, int start, int length)
{ {
Bind(); Bind();
GL.BufferSubData(BufferTarget.ArrayBuffer, GL.BufferSubData(BufferTarget.ArrayBuffer,
IntPtr.Zero, new IntPtr(VertexSize * start),
new IntPtr(VertexSize * length), new IntPtr(VertexSize * length),
data); data);
ErrorHandler.CheckGlError(); ErrorHandler.CheckGlError();