Add index buffer SpriteRenderer

This commit is contained in:
Gustas
2023-08-28 11:22:52 +03:00
committed by Matthias Mailänder
parent 2763e1502b
commit 3e6123f6f6
3 changed files with 47 additions and 77 deletions

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Graphics
static readonly float3 Offset = new(0.5f, 0.5f, 0f); static readonly float3 Offset = new(0.5f, 0.5f, 0f);
readonly SpriteRenderer parent; readonly SpriteRenderer parent;
readonly Vertex[] vertices = new Vertex[6]; readonly Vertex[] vertices = new Vertex[4];
public RgbaColorRenderer(SpriteRenderer parent) 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[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[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[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[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);
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) 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[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[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[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[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); parent.DrawRGBAQuad(vertices, blendMode);
vertices[5] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0);
parent.DrawRGBAVertices(vertices, blendMode);
} }
/// <summary> /// <summary>
@@ -160,10 +156,8 @@ namespace OpenRA.Graphics
vertices[0] = new Vertex(ca + Offset, r, g, b, a, 0, 0); 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[1] = new Vertex(cb + Offset, r, g, b, a, 0, 0);
vertices[2] = new Vertex(cc + 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[3] = new Vertex(cd + Offset, r, g, b, a, 0, 0);
vertices[4] = new Vertex(cd + Offset, r, g, b, a, 0, 0); parent.DrawRGBAQuad(vertices, blendMode);
vertices[5] = new Vertex(ca + Offset, r, g, b, a, 0, 0);
parent.DrawRGBAVertices(vertices, blendMode);
// Advance line segment // Advance line segment
end = next; end = next;
@@ -200,20 +194,6 @@ namespace OpenRA.Graphics
DrawPolygon(new[] { tl, tr, br, bl }, width, color, blendMode); 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) 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); 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[0] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0);
vertices[1] = new Vertex(b + 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[2] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0);
vertices[3] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0); vertices[3] = new Vertex(d + Offset, cr, cg, cb, ca, 0, 0);
vertices[4] = new Vertex(d + Offset, cr, cg, cb, ca, 0, 0); parent.DrawRGBAQuad(vertices, blendMode);
vertices[5] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0);
parent.DrawRGBAVertices(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) 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[0] = VertexWithColor(a + Offset, topLeftColor);
vertices[1] = VertexWithColor(b + Offset, topRightColor); vertices[1] = VertexWithColor(b + Offset, topRightColor);
vertices[2] = VertexWithColor(c + Offset, bottomRightColor); vertices[2] = VertexWithColor(c + Offset, bottomRightColor);
vertices[3] = VertexWithColor(c + Offset, bottomRightColor); vertices[3] = VertexWithColor(d + Offset, bottomLeftColor);
vertices[4] = VertexWithColor(d + Offset, bottomLeftColor);
vertices[5] = VertexWithColor(a + Offset, topLeftColor);
parent.DrawRGBAVertices(vertices, blendMode); parent.DrawRGBAQuad(vertices, blendMode);
} }
static Vertex VertexWithColor(in float3 xyz, Color color) static Vertex VertexWithColor(in float3 xyz, Color color)

View File

@@ -29,8 +29,8 @@ namespace OpenRA.Graphics
readonly Sheet[] sheets = new Sheet[SheetCount]; readonly Sheet[] sheets = new Sheet[SheetCount];
BlendMode currentBlend = BlendMode.Alpha; BlendMode currentBlend = BlendMode.Alpha;
int nv = 0; int vertexCount = 0;
int ns = 0; int sheetCount = 0;
public SpriteRenderer(Renderer renderer, IShader shader) public SpriteRenderer(Renderer renderer, IShader shader)
{ {
@@ -41,9 +41,9 @@ namespace OpenRA.Graphics
public void Flush() 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()); shader.SetTexture(SheetIndexToTextureName[i], sheets[i].GetTexture());
sheets[i] = null; sheets[i] = null;
@@ -52,12 +52,11 @@ namespace OpenRA.Graphics
renderer.Context.SetBlendMode(currentBlend); renderer.Context.SetBlendMode(currentBlend);
shader.PrepareRender(); shader.PrepareRender();
// PERF: The renderer may choose to replace vertices with a different temporary buffer. renderer.DrawQuadBatch(ref vertices, vertexCount);
renderer.DrawBatch(ref vertices, nv, PrimitiveType.TriangleList);
renderer.Context.SetBlendMode(BlendMode.None); renderer.Context.SetBlendMode(BlendMode.None);
nv = 0; vertexCount = 0;
ns = 0; sheetCount = 0;
} }
} }
@@ -65,7 +64,7 @@ namespace OpenRA.Graphics
{ {
renderer.CurrentBatchRenderer = this; renderer.CurrentBatchRenderer = this;
if (s.BlendMode != currentBlend || nv + 6 > renderer.TempVertexBufferSize) if (s.BlendMode != currentBlend || vertexCount + 4 > renderer.TempVertexBufferSize)
Flush(); Flush();
currentBlend = s.BlendMode; currentBlend = s.BlendMode;
@@ -73,7 +72,7 @@ namespace OpenRA.Graphics
// Check if the sheet (or secondary data sheet) have already been mapped // Check if the sheet (or secondary data sheet) have already been mapped
var sheet = s.Sheet; var sheet = s.Sheet;
var sheetIndex = 0; var sheetIndex = 0;
for (; sheetIndex < ns; sheetIndex++) for (; sheetIndex < sheetCount; sheetIndex++)
if (sheets[sheetIndex] == sheet) if (sheets[sheetIndex] == sheet)
break; break;
@@ -82,7 +81,7 @@ namespace OpenRA.Graphics
if (ss != null) if (ss != null)
{ {
var secondarySheet = ss.SecondarySheet; var secondarySheet = ss.SecondarySheet;
for (; secondarySheetIndex < ns; secondarySheetIndex++) for (; secondarySheetIndex < sheetCount; secondarySheetIndex++)
if (sheets[secondarySheetIndex] == secondarySheet) if (sheets[secondarySheetIndex] == secondarySheet)
break; break;
@@ -101,16 +100,16 @@ namespace OpenRA.Graphics
secondarySheetIndex = ss != null && ss.SecondarySheet != sheet ? 1 : 0; secondarySheetIndex = ss != null && ss.SecondarySheet != sheet ? 1 : 0;
} }
if (sheetIndex >= ns) if (sheetIndex >= sheetCount)
{ {
sheets[sheetIndex] = sheet; sheets[sheetIndex] = sheet;
ns++; sheetCount++;
} }
if (secondarySheetIndex >= ns && ss != null) if (secondarySheetIndex >= sheetCount && ss != null)
{ {
sheets[secondarySheetIndex] = ss.SecondarySheet; sheets[secondarySheetIndex] = ss.SecondarySheet;
ns++; sheetCount++;
} }
return new int2(sheetIndex, secondarySheetIndex); 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) internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, in float3 scale, float rotation = 0f)
{ {
var samplers = SetRenderStateForSprite(s); 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); 1f, rotation);
nv += 6; vertexCount += 4;
} }
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, float scale, float rotation = 0f) internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, float scale, float rotation = 0f)
{ {
var samplers = SetRenderStateForSprite(s); 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); 1f, rotation);
nv += 6; vertexCount += 4;
} }
public void DrawSprite(Sprite s, PaletteReference pal, in float3 location, float scale = 1f, float rotation = 0f) 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) float rotation = 0f)
{ {
var samplers = SetRenderStateForSprite(s); 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); rotation);
nv += 6; vertexCount += 4;
} }
public void DrawSprite(Sprite s, PaletteReference pal, in float3 location, float scale, in float3 tint, float alpha, 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) 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); var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, paletteTextureIndex, tint, alpha, nv); Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, paletteTextureIndex, tint, alpha, vertexCount);
nv += 6; vertexCount += 4;
} }
public void DrawVertexBuffer(IVertexBuffer<Vertex> buffer, IIndexBuffer indices, int start, int length, IEnumerable<Sheet> sheets, BlendMode blendMode) public void DrawVertexBuffer(IVertexBuffer<Vertex> buffer, IIndexBuffer indices, int start, int length, IEnumerable<Sheet> sheets, BlendMode blendMode)
@@ -187,7 +186,7 @@ namespace OpenRA.Graphics
renderer.Context.SetBlendMode(blendMode); renderer.Context.SetBlendMode(blendMode);
shader.PrepareRender(); shader.PrepareRender();
renderer.DrawBatch(buffer, indices, length, UintSize * start); renderer.DrawQuadBatch(buffer, indices, length, UintSize * start);
renderer.Context.SetBlendMode(BlendMode.None); renderer.Context.SetBlendMode(BlendMode.None);
} }
@@ -198,16 +197,17 @@ namespace OpenRA.Graphics
} }
// For RGBAColorRenderer // For RGBAColorRenderer
internal void DrawRGBAVertices(Vertex[] v, BlendMode blendMode) internal void DrawRGBAQuad(Vertex[] v, BlendMode blendMode)
{ {
renderer.CurrentBatchRenderer = this; renderer.CurrentBatchRenderer = this;
if (currentBlend != blendMode || nv + v.Length > renderer.TempVertexBufferSize) if (currentBlend != blendMode || vertexCount + 4 > renderer.TempVertexBufferSize)
Flush(); Flush();
currentBlend = blendMode; 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) public void SetPalette(ITexture palette, ITexture colorShifts)

View File

@@ -97,7 +97,7 @@ namespace OpenRA
RgbaColorRenderer = new RgbaColorRenderer(SpriteRenderer); RgbaColorRenderer = new RgbaColorRenderer(SpriteRenderer);
tempVertexBuffer = Context.CreateVertexBuffer(TempVertexBufferSize); tempVertexBuffer = Context.CreateVertexBuffer(TempVertexBufferSize);
quadIndexBuffer = Context.CreateQuadIndexBuffer(TempIndexBufferSize); quadIndexBuffer = Context.CreateIndexBuffer(Util.CreateQuadIndices(TempIndexBufferSize / 6));
} }
static Size GetResolution(GraphicSettings graphicsSettings) static Size GetResolution(GraphicSettings graphicsSettings)
@@ -331,18 +331,6 @@ namespace OpenRA
renderType = RenderType.None; 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<T>(IVertexBuffer<T> vertices, public void DrawBatch<T>(IVertexBuffer<T> vertices,
int firstVertex, int numVertices, PrimitiveType type) int firstVertex, int numVertices, PrimitiveType type)
where T : struct where T : struct
@@ -352,7 +340,13 @@ namespace OpenRA
PerfHistory.Increment("batches", 1); PerfHistory.Increment("batches", 1);
} }
public void DrawBatch<T>(IVertexBuffer<T> 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<T>(IVertexBuffer<T> vertices, IIndexBuffer indices, int numIndices, int start)
where T : struct where T : struct
{ {
vertices.Bind(); vertices.Bind();