Update terrain layer when the terrain data changes.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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() { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user