From 3e6123f6f65461c38b93b0c94bd000309e6e56a0 Mon Sep 17 00:00:00 2001 From: Gustas Date: Mon, 28 Aug 2023 11:22:52 +0300 Subject: [PATCH] Add index buffer SpriteRenderer --- OpenRA.Game/Graphics/RgbaColorRenderer.cs | 46 +++++-------------- OpenRA.Game/Graphics/SpriteRenderer.cs | 56 +++++++++++------------ OpenRA.Game/Renderer.cs | 22 ++++----- 3 files changed, 47 insertions(+), 77 deletions(-) diff --git a/OpenRA.Game/Graphics/RgbaColorRenderer.cs b/OpenRA.Game/Graphics/RgbaColorRenderer.cs index 591542633e..6927b39f0f 100644 --- a/OpenRA.Game/Graphics/RgbaColorRenderer.cs +++ b/OpenRA.Game/Graphics/RgbaColorRenderer.cs @@ -21,7 +21,7 @@ namespace OpenRA.Graphics static readonly float3 Offset = new(0.5f, 0.5f, 0f); readonly SpriteRenderer parent; - readonly Vertex[] vertices = new Vertex[6]; + readonly Vertex[] vertices = new Vertex[4]; public RgbaColorRenderer(SpriteRenderer parent) { @@ -48,11 +48,9 @@ namespace OpenRA.Graphics vertices[0] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0); vertices[1] = new Vertex(start + corner + Offset, sr, sg, sb, sa, 0, 0); vertices[2] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0); - vertices[3] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0); - vertices[4] = new Vertex(end - corner + Offset, er, eg, eb, ea, 0, 0); - vertices[5] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0); + vertices[3] = new Vertex(end - corner + Offset, er, eg, eb, ea, 0, 0); - parent.DrawRGBAVertices(vertices, blendMode); + parent.DrawRGBAQuad(vertices, blendMode); } public void DrawLine(in float3 start, in float3 end, float width, Color color, BlendMode blendMode = BlendMode.Alpha) @@ -69,10 +67,8 @@ namespace OpenRA.Graphics vertices[0] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0); vertices[1] = new Vertex(start + corner + Offset, r, g, b, a, 0, 0); vertices[2] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0); - vertices[3] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0); - vertices[4] = new Vertex(end - corner + Offset, r, g, b, a, 0, 0); - vertices[5] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0); - parent.DrawRGBAVertices(vertices, blendMode); + vertices[3] = new Vertex(end - corner + Offset, r, g, b, a, 0, 0); + parent.DrawRGBAQuad(vertices, blendMode); } /// @@ -160,10 +156,8 @@ namespace OpenRA.Graphics vertices[0] = new Vertex(ca + Offset, r, g, b, a, 0, 0); vertices[1] = new Vertex(cb + Offset, r, g, b, a, 0, 0); vertices[2] = new Vertex(cc + Offset, r, g, b, a, 0, 0); - vertices[3] = new Vertex(cc + Offset, r, g, b, a, 0, 0); - vertices[4] = new Vertex(cd + Offset, r, g, b, a, 0, 0); - vertices[5] = new Vertex(ca + Offset, r, g, b, a, 0, 0); - parent.DrawRGBAVertices(vertices, blendMode); + vertices[3] = new Vertex(cd + Offset, r, g, b, a, 0, 0); + parent.DrawRGBAQuad(vertices, blendMode); // Advance line segment end = next; @@ -200,20 +194,6 @@ namespace OpenRA.Graphics DrawPolygon(new[] { tl, tr, br, bl }, width, color, blendMode); } - public void FillTriangle(in float3 a, in float3 b, in float3 c, Color color, BlendMode blendMode = BlendMode.Alpha) - { - color = Util.PremultiplyAlpha(color); - var cr = color.R / 255.0f; - var cg = color.G / 255.0f; - var cb = color.B / 255.0f; - var ca = color.A / 255.0f; - - vertices[0] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0); - vertices[1] = new Vertex(b + Offset, cr, cg, cb, ca, 0, 0); - vertices[2] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0); - parent.DrawRGBAVertices(vertices, blendMode); - } - public void FillRect(in float3 tl, in float3 br, Color color, BlendMode blendMode = BlendMode.Alpha) { var tr = new float3(br.X, tl.Y, tl.Z); @@ -232,10 +212,8 @@ namespace OpenRA.Graphics vertices[0] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0); vertices[1] = new Vertex(b + Offset, cr, cg, cb, ca, 0, 0); vertices[2] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0); - vertices[3] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0); - vertices[4] = new Vertex(d + Offset, cr, cg, cb, ca, 0, 0); - vertices[5] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0); - parent.DrawRGBAVertices(vertices, blendMode); + vertices[3] = new Vertex(d + Offset, cr, cg, cb, ca, 0, 0); + parent.DrawRGBAQuad(vertices, blendMode); } public void FillRect(in float3 a, in float3 b, in float3 c, in float3 d, Color topLeftColor, Color topRightColor, Color bottomRightColor, Color bottomLeftColor, BlendMode blendMode = BlendMode.Alpha) @@ -243,11 +221,9 @@ namespace OpenRA.Graphics vertices[0] = VertexWithColor(a + Offset, topLeftColor); vertices[1] = VertexWithColor(b + Offset, topRightColor); vertices[2] = VertexWithColor(c + Offset, bottomRightColor); - vertices[3] = VertexWithColor(c + Offset, bottomRightColor); - vertices[4] = VertexWithColor(d + Offset, bottomLeftColor); - vertices[5] = VertexWithColor(a + Offset, topLeftColor); + vertices[3] = VertexWithColor(d + Offset, bottomLeftColor); - parent.DrawRGBAVertices(vertices, blendMode); + parent.DrawRGBAQuad(vertices, blendMode); } static Vertex VertexWithColor(in float3 xyz, Color color) diff --git a/OpenRA.Game/Graphics/SpriteRenderer.cs b/OpenRA.Game/Graphics/SpriteRenderer.cs index 4819a5570e..cf5b10f9c7 100644 --- a/OpenRA.Game/Graphics/SpriteRenderer.cs +++ b/OpenRA.Game/Graphics/SpriteRenderer.cs @@ -29,8 +29,8 @@ namespace OpenRA.Graphics readonly Sheet[] sheets = new Sheet[SheetCount]; BlendMode currentBlend = BlendMode.Alpha; - int nv = 0; - int ns = 0; + int vertexCount = 0; + int sheetCount = 0; public SpriteRenderer(Renderer renderer, IShader shader) { @@ -41,9 +41,9 @@ namespace OpenRA.Graphics public void Flush() { - if (nv > 0) + if (vertexCount > 0) { - for (var i = 0; i < ns; i++) + for (var i = 0; i < sheetCount; i++) { shader.SetTexture(SheetIndexToTextureName[i], sheets[i].GetTexture()); sheets[i] = null; @@ -52,12 +52,11 @@ namespace OpenRA.Graphics renderer.Context.SetBlendMode(currentBlend); shader.PrepareRender(); - // PERF: The renderer may choose to replace vertices with a different temporary buffer. - renderer.DrawBatch(ref vertices, nv, PrimitiveType.TriangleList); + renderer.DrawQuadBatch(ref vertices, vertexCount); renderer.Context.SetBlendMode(BlendMode.None); - nv = 0; - ns = 0; + vertexCount = 0; + sheetCount = 0; } } @@ -65,7 +64,7 @@ namespace OpenRA.Graphics { renderer.CurrentBatchRenderer = this; - if (s.BlendMode != currentBlend || nv + 6 > renderer.TempVertexBufferSize) + if (s.BlendMode != currentBlend || vertexCount + 4 > renderer.TempVertexBufferSize) Flush(); currentBlend = s.BlendMode; @@ -73,7 +72,7 @@ namespace OpenRA.Graphics // Check if the sheet (or secondary data sheet) have already been mapped var sheet = s.Sheet; var sheetIndex = 0; - for (; sheetIndex < ns; sheetIndex++) + for (; sheetIndex < sheetCount; sheetIndex++) if (sheets[sheetIndex] == sheet) break; @@ -82,7 +81,7 @@ namespace OpenRA.Graphics if (ss != null) { var secondarySheet = ss.SecondarySheet; - for (; secondarySheetIndex < ns; secondarySheetIndex++) + for (; secondarySheetIndex < sheetCount; secondarySheetIndex++) if (sheets[secondarySheetIndex] == secondarySheet) break; @@ -101,16 +100,16 @@ namespace OpenRA.Graphics secondarySheetIndex = ss != null && ss.SecondarySheet != sheet ? 1 : 0; } - if (sheetIndex >= ns) + if (sheetIndex >= sheetCount) { sheets[sheetIndex] = sheet; - ns++; + sheetCount++; } - if (secondarySheetIndex >= ns && ss != null) + if (secondarySheetIndex >= sheetCount && ss != null) { sheets[secondarySheetIndex] = ss.SecondarySheet; - ns++; + sheetCount++; } return new int2(sheetIndex, secondarySheetIndex); @@ -133,17 +132,17 @@ namespace OpenRA.Graphics internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, in float3 scale, float rotation = 0f) { var samplers = SetRenderStateForSprite(s); - Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, float3.Ones, + Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, vertexCount, scale * s.Size, float3.Ones, 1f, rotation); - nv += 6; + vertexCount += 4; } internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, float scale, float rotation = 0f) { var samplers = SetRenderStateForSprite(s); - Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, float3.Ones, + Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, vertexCount, scale * s.Size, float3.Ones, 1f, rotation); - nv += 6; + vertexCount += 4; } public void DrawSprite(Sprite s, PaletteReference pal, in float3 location, float scale = 1f, float rotation = 0f) @@ -155,9 +154,9 @@ namespace OpenRA.Graphics float rotation = 0f) { var samplers = SetRenderStateForSprite(s); - Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, tint, alpha, + Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, vertexCount, scale * s.Size, tint, alpha, rotation); - nv += 6; + vertexCount += 4; } public void DrawSprite(Sprite s, PaletteReference pal, in float3 location, float scale, in float3 tint, float alpha, @@ -169,8 +168,8 @@ namespace OpenRA.Graphics internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 a, in float3 b, in float3 c, in float3 d, in float3 tint, float alpha) { var samplers = SetRenderStateForSprite(s); - Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, paletteTextureIndex, tint, alpha, nv); - nv += 6; + Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, paletteTextureIndex, tint, alpha, vertexCount); + vertexCount += 4; } public void DrawVertexBuffer(IVertexBuffer buffer, IIndexBuffer indices, int start, int length, IEnumerable sheets, BlendMode blendMode) @@ -187,7 +186,7 @@ namespace OpenRA.Graphics renderer.Context.SetBlendMode(blendMode); shader.PrepareRender(); - renderer.DrawBatch(buffer, indices, length, UintSize * start); + renderer.DrawQuadBatch(buffer, indices, length, UintSize * start); renderer.Context.SetBlendMode(BlendMode.None); } @@ -198,16 +197,17 @@ namespace OpenRA.Graphics } // For RGBAColorRenderer - internal void DrawRGBAVertices(Vertex[] v, BlendMode blendMode) + internal void DrawRGBAQuad(Vertex[] v, BlendMode blendMode) { renderer.CurrentBatchRenderer = this; - if (currentBlend != blendMode || nv + v.Length > renderer.TempVertexBufferSize) + if (currentBlend != blendMode || vertexCount + 4 > renderer.TempVertexBufferSize) Flush(); currentBlend = blendMode; - Array.Copy(v, 0, vertices, nv, v.Length); - nv += v.Length; + + Array.Copy(v, 0, vertices, vertexCount, v.Length); + vertexCount += 4; } public void SetPalette(ITexture palette, ITexture colorShifts) diff --git a/OpenRA.Game/Renderer.cs b/OpenRA.Game/Renderer.cs index 16bf8ba77b..019d7fe0e9 100644 --- a/OpenRA.Game/Renderer.cs +++ b/OpenRA.Game/Renderer.cs @@ -97,7 +97,7 @@ namespace OpenRA RgbaColorRenderer = new RgbaColorRenderer(SpriteRenderer); tempVertexBuffer = Context.CreateVertexBuffer(TempVertexBufferSize); - quadIndexBuffer = Context.CreateQuadIndexBuffer(TempIndexBufferSize); + quadIndexBuffer = Context.CreateIndexBuffer(Util.CreateQuadIndices(TempIndexBufferSize / 6)); } static Size GetResolution(GraphicSettings graphicsSettings) @@ -331,18 +331,6 @@ namespace OpenRA renderType = RenderType.None; } - public void DrawBatch(Vertex[] vertices, int numVertices, PrimitiveType type) - { - tempBuffer.SetData(vertices, numVertices); - DrawBatch(tempBuffer, 0, numVertices, type); - } - - public void DrawBatch(ref Vertex[] vertices, int numVertices, PrimitiveType type) - { - tempBuffer.SetData(ref vertices, numVertices); - DrawBatch(tempBuffer, 0, numVertices, type); - } - public void DrawBatch(IVertexBuffer vertices, int firstVertex, int numVertices, PrimitiveType type) where T : struct @@ -352,7 +340,13 @@ namespace OpenRA PerfHistory.Increment("batches", 1); } - public void DrawBatch(IVertexBuffer vertices, IIndexBuffer indices, int numIndices, int start) + public void DrawQuadBatch(ref Vertex[] vertices, int numVertices) + { + tempVertexBuffer.SetData(ref vertices, numVertices); + DrawQuadBatch(tempVertexBuffer, quadIndexBuffer, numVertices / 4 * 6, 0); + } + + public void DrawQuadBatch(IVertexBuffer vertices, IIndexBuffer indices, int numIndices, int start) where T : struct { vertices.Bind();