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

@@ -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);