Add StaticIndexBuffer

This commit is contained in:
Gustas
2023-08-24 14:38:01 +03:00
committed by Matthias Mailänder
parent 7e9619b41b
commit f6c1453b5b
6 changed files with 117 additions and 0 deletions

View File

@@ -84,6 +84,7 @@ namespace OpenRA
public interface IGraphicsContext : IDisposable
{
IVertexBuffer<Vertex> CreateVertexBuffer(int size);
IIndexBuffer CreateIndexBuffer(uint[] indices);
Vertex[] CreateVertices(int size);
ITexture CreateTexture();
IFrameBuffer CreateFrameBuffer(Size s);
@@ -114,6 +115,11 @@ namespace OpenRA
void SetData(T[] vertices, int offset, int start, int length);
}
public interface IIndexBuffer : IDisposable
{
void Bind();
}
public interface IShader
{
void SetBool(string name, bool value);

View File

@@ -20,6 +20,16 @@ namespace OpenRA.Graphics
// yes, our channel order is nuts.
static readonly int[] ChannelMasks = { 2, 1, 0, 3 };
public static uint[] CreateQuadIndices(int quads)
{
var indices = new uint[quads * 6];
ReadOnlySpan<uint> cornerVertexMap = stackalloc uint[] { 0, 1, 2, 2, 3, 0 };
for (var i = 0; i < indices.Length; i++)
indices[i] = cornerVertexMap[i % 6] + (uint)(4 * (i / 6));
return indices;
}
public static void FastCreateQuad(Vertex[] vertices, in float3 o, Sprite r, int2 samplers, float paletteTextureIndex, int nv,
in float3 size, in float3 tint, float alpha, float rotation = 0f)
{

View File

@@ -131,6 +131,8 @@ namespace OpenRA.Platforms.Default
public const int GL_TEXTURE_MAX_LEVEL = 0x813D;
public const int GL_ARRAY_BUFFER = 0x8892;
public const int GL_ELEMENT_ARRAY_BUFFER = 0x8893;
public const int GL_STATIC_DRAW = 0x88E4;
public const int GL_DYNAMIC_DRAW = 0x88E8;
public const int GL_TEXTURE0 = 0x84C0;

View File

@@ -68,6 +68,12 @@ namespace OpenRA.Platforms.Default
return new VertexBuffer<Vertex>(size);
}
public IIndexBuffer CreateIndexBuffer(uint[] indices)
{
VerifyThreadAffinity();
return new StaticIndexBuffer(indices);
}
public Vertex[] CreateVertices(int size)
{
VerifyThreadAffinity();

View File

@@ -0,0 +1,62 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System;
using System.Runtime.InteropServices;
namespace OpenRA.Platforms.Default
{
sealed class StaticIndexBuffer : ThreadAffine, IDisposable, IIndexBuffer
{
const int UintSize = 4;
uint buffer;
bool disposed;
public StaticIndexBuffer(uint[] indices)
{
OpenGL.glGenBuffers(1, out buffer);
OpenGL.CheckGLError();
Bind();
var ptr = GCHandle.Alloc(indices, GCHandleType.Pinned);
try
{
OpenGL.glBufferData(OpenGL.GL_ELEMENT_ARRAY_BUFFER,
new IntPtr(UintSize * indices.Length),
ptr.AddrOfPinnedObject(),
OpenGL.GL_STATIC_DRAW);
}
finally
{
ptr.Free();
}
OpenGL.CheckGLError();
}
public void Bind()
{
VerifyThreadAffinity();
OpenGL.glBindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, buffer);
OpenGL.CheckGLError();
}
public void Dispose()
{
if (disposed)
return;
disposed = true;
OpenGL.glDeleteBuffers(1, ref buffer);
OpenGL.CheckGLError();
}
}
}

View File

@@ -46,6 +46,7 @@ namespace OpenRA.Platforms.Default
Func<object, IFrameBuffer> getCreateFrameBuffer;
Func<object, IShader> getCreateShader;
Func<object, IVertexBuffer<Vertex>> getCreateVertexBuffer;
Func<object, IIndexBuffer> getCreateIndexBuffer;
Action<object> doDrawPrimitives;
Action<object> doEnableScissor;
Action<object> doSetBlendMode;
@@ -94,6 +95,7 @@ namespace OpenRA.Platforms.Default
};
getCreateShader = name => new ThreadedShader(this, context.CreateShader((string)name));
getCreateVertexBuffer = length => new ThreadedVertexBuffer(this, context.CreateVertexBuffer((int)length));
getCreateIndexBuffer = indices => new ThreadedIndexBuffer(this, context.CreateIndexBuffer((uint[])indices));
doDrawPrimitives =
tuple =>
{
@@ -404,6 +406,11 @@ namespace OpenRA.Platforms.Default
return Send(getCreateVertexBuffer, length);
}
public IIndexBuffer CreateIndexBuffer(uint[] indices)
{
return Send(getCreateIndexBuffer, indices);
}
public Vertex[] CreateVertices(int size)
{
return GetVertices(size);
@@ -563,6 +570,30 @@ namespace OpenRA.Platforms.Default
}
}
sealed class ThreadedIndexBuffer : IIndexBuffer
{
readonly ThreadedGraphicsContext device;
readonly Action bind;
readonly Action dispose;
public ThreadedIndexBuffer(ThreadedGraphicsContext device, IIndexBuffer indexBuffer)
{
this.device = device;
bind = indexBuffer.Bind;
dispose = indexBuffer.Dispose;
}
public void Bind()
{
device.Post(bind);
}
public void Dispose()
{
device.Post(dispose);
}
}
sealed class ThreadedTexture : ITextureInternal
{
readonly ThreadedGraphicsContext device;