Initialise VertexBuffers immediately

This commit is contained in:
Gustas
2025-02-22 16:04:23 +02:00
committed by Paul Chote
parent a2096b6768
commit 39aec39364
10 changed files with 63 additions and 18 deletions

View File

@@ -83,7 +83,8 @@ namespace OpenRA
public interface IGraphicsContext : IDisposable
{
IVertexBuffer<T> CreateVertexBuffer<T>(int size) where T : struct;
IVertexBuffer<T> CreateEmptyVertexBuffer<T>(int size) where T : struct;
IVertexBuffer<T> CreateVertexBuffer<T>(T[] data, bool dynamic = true) where T : struct;
T[] CreateVertices<T>(int size) where T : struct;
IIndexBuffer CreateIndexBuffer(uint[] indices);
ITexture CreateTexture();

View File

@@ -51,7 +51,7 @@ namespace OpenRA.Graphics
vertexRowStride = 4 * map.MapSize.X;
vertices = new Vertex[vertexRowStride * map.MapSize.Y];
vertexBuffer = Game.Renderer.Context.CreateVertexBuffer<Vertex>(vertices.Length);
vertexBuffer = Game.Renderer.Context.CreateEmptyVertexBuffer<Vertex>(vertices.Length);
indexRowStride = 6 * map.MapSize.X;
lock (IndexBuffers)

View File

@@ -107,7 +107,7 @@ namespace OpenRA
RgbaSpriteRenderer = new RgbaSpriteRenderer(SpriteRenderer);
RgbaColorRenderer = new RgbaColorRenderer(SpriteRenderer);
tempVertexBuffer = Context.CreateVertexBuffer<Vertex>(TempVertexBufferSize);
tempVertexBuffer = Context.CreateEmptyVertexBuffer<Vertex>(TempVertexBufferSize);
quadIndexBuffer = Context.CreateIndexBuffer(Util.CreateQuadIndices(TempIndexBufferSize / 6));
worldBufferSnapshot = Context.CreateTexture();
}
@@ -406,9 +406,9 @@ namespace OpenRA
return Context.CreateShader(bindings);
}
public IVertexBuffer<T> CreateVertexBuffer<T>(int length) where T : struct
public IVertexBuffer<T> CreateVertexBuffer<T>(T[] data, bool dynamic) where T : struct
{
return Context.CreateVertexBuffer<T>(length);
return Context.CreateVertexBuffer(data, dynamic);
}
public void EnableScissor(Rectangle rect)

View File

@@ -195,8 +195,7 @@ namespace OpenRA.Mods.Cnc.Graphics
public void RefreshBuffer()
{
vertexBuffer?.Dispose();
vertexBuffer = Game.Renderer.CreateVertexBuffer<ModelVertex>(totalVertexCount);
vertexBuffer.SetData(vertices.SelectMany(v => v).ToArray(), totalVertexCount);
vertexBuffer = Game.Renderer.CreateVertexBuffer(vertices.SelectMany(v => v).ToArray(), false);
cachedVertexCount = totalVertexCount;
}

View File

@@ -37,7 +37,6 @@ namespace OpenRA.Mods.Cnc.Traits
shader = renderer.CreateShader(new RenderPostProcessPassTexturedShaderBindings("vortex"));
vortexSheet = new Sheet(SheetType.BGRA, new Size(512, 512));
vortexBuffer = renderer.CreateVertexBuffer<RenderPostProcessPassTexturedVertex>(288);
var vertices = new RenderPostProcessPassTexturedVertex[288];
var data = vortexSheet.GetData();
@@ -72,7 +71,7 @@ namespace OpenRA.Mods.Cnc.Traits
vertices[j++] = new RenderPostProcessPassTexturedVertex(-32, -32, tl.X, tl.Y);
}
vortexBuffer.SetData(ref vertices, 288);
vortexBuffer = renderer.CreateVertexBuffer(vertices, false);
vortexSheet.CommitBufferedData();
}

View File

@@ -36,8 +36,7 @@ namespace OpenRA.Mods.Common.Traits
new(-1, -1)
};
buffer = renderer.CreateVertexBuffer<RenderPostProcessPassVertex>(6);
buffer.SetData(ref vertices, 6);
buffer = renderer.CreateVertexBuffer(vertices, false);
}
PostProcessPassType IRenderPostProcessPass.Type => type;

View File

@@ -42,7 +42,6 @@ namespace OpenRA.Mods.D2k.Traits
Info = info;
renderer = Game.Renderer;
shader = renderer.CreateShader(new RenderPostProcessPassTexturedShaderBindings("sonic"));
buffer = renderer.CreateVertexBuffer<RenderPostProcessPassTexturedVertex>(6);
var r = 0.5f * info.Size;
shader.SetVec("Scale", r * (1f / info.Zoom - 1));
@@ -56,7 +55,7 @@ namespace OpenRA.Mods.D2k.Traits
new(-r, -r, -1, -1)
};
buffer.SetData(ref vertices, 6);
buffer = renderer.CreateVertexBuffer(vertices, false);
}
public void Draw(float3 pos)

View File

@@ -49,12 +49,18 @@ namespace OpenRA.Platforms.Default
OpenGL.CheckGLError();
}
public IVertexBuffer<T> CreateVertexBuffer<T>(int size) where T : struct
public IVertexBuffer<T> CreateEmptyVertexBuffer<T>(int size) where T : struct
{
VerifyThreadAffinity();
return new VertexBuffer<T>(size);
}
public IVertexBuffer<T> CreateVertexBuffer<T>(T[] data, bool dynamic = true) where T : struct
{
VerifyThreadAffinity();
return new VertexBuffer<T>(data, dynamic);
}
public IIndexBuffer CreateIndexBuffer(uint[] indices)
{
VerifyThreadAffinity();

View File

@@ -45,6 +45,7 @@ namespace OpenRA.Platforms.Default
Func<ITexture> getCreateTexture;
Func<object, IFrameBuffer> getCreateFrameBuffer;
Func<object, IShader> getCreateShader;
Func<object, object> getCreateEmptyVertexBuffer;
Func<object, object> getCreateVertexBuffer;
Func<object, IIndexBuffer> getCreateIndexBuffer;
Action<object> doDrawPrimitives;
@@ -96,11 +97,25 @@ namespace OpenRA.Platforms.Default
context.CreateFrameBuffer(t.Item1, (ITextureInternal)CreateTexture(), t.Item2));
};
getCreateShader = bindings => new ThreadedShader(this, context.CreateShader((IShaderBindings)bindings));
getCreateVertexBuffer =
getCreateEmptyVertexBuffer =
tuple =>
{
(object t, var type) = ((int, Type))tuple;
var vertexBuffer = context.GetType().GetMethod(nameof(CreateVertexBuffer)).MakeGenericMethod(type).Invoke(context, [t]);
var vertexBuffer = context.GetType()
.GetMethod(nameof(CreateEmptyVertexBuffer))
.MakeGenericMethod(type)
.Invoke(context, [t]);
return typeof(ThreadedVertexBuffer<>).MakeGenericType(type).GetConstructors()[0].Invoke([this, vertexBuffer]);
};
getCreateVertexBuffer =
tuple =>
{
var (array, dynamic, type) = ((object, bool, Type))tuple;
var vertexBuffer = context.GetType()
.GetMethod(nameof(CreateVertexBuffer))
.MakeGenericMethod(type)
.Invoke(context, [array, dynamic]);
return typeof(ThreadedVertexBuffer<>).MakeGenericType(type).GetConstructors()[0].Invoke([this, vertexBuffer]);
};
getCreateIndexBuffer = indices => new ThreadedIndexBuffer(this, context.CreateIndexBuffer((uint[])indices));
@@ -426,9 +441,14 @@ namespace OpenRA.Platforms.Default
return Send(getCreateTexture);
}
public IVertexBuffer<T> CreateVertexBuffer<T>(int size) where T : struct
public IVertexBuffer<T> CreateEmptyVertexBuffer<T>(int size) where T : struct
{
return (IVertexBuffer<T>)Send(getCreateVertexBuffer, (size, typeof(T)));
return (IVertexBuffer<T>)Send(getCreateEmptyVertexBuffer, (size, typeof(T)));
}
public IVertexBuffer<T> CreateVertexBuffer<T>(T[] data, bool dynamic = true) where T : struct
{
return (IVertexBuffer<T>)Send(getCreateVertexBuffer, ((object)data, dynamic, typeof(T)));
}
public IIndexBuffer CreateIndexBuffer(uint[] indices)

View File

@@ -55,6 +55,28 @@ namespace OpenRA.Platforms.Default
}
}
public VertexBuffer(T[] data, bool dynamic = true)
{
OpenGL.glGenBuffers(1, out buffer);
OpenGL.CheckGLError();
Bind();
var ptr = GCHandle.Alloc(data, GCHandleType.Pinned);
try
{
OpenGL.glBufferData(OpenGL.GL_ARRAY_BUFFER,
new IntPtr(VertexSize * data.Length),
ptr.AddrOfPinnedObject(),
dynamic ? OpenGL.GL_DYNAMIC_DRAW : OpenGL.GL_STATIC_DRAW);
}
finally
{
ptr.Free();
}
OpenGL.CheckGLError();
}
public void SetData(T[] data, int length)
{
SetData(data, 0, 0, length);