This commit is contained in:
2024-12-04 22:35:04 +03:00
commit 3f1740f41f
43 changed files with 1757 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
using System.Reflection;
using System.Runtime.InteropServices;
using Engine.Renderer.Buffer.Vertex;
using OpenTK.Graphics.OpenGL;
using Serilog;
namespace Engine.Renderer.Buffer;
public class VertexArray : OpenGlObject
{
// private IndexBuffer? _boundIndexBuffer;
// private readonly Dictionary<int, VertexBuffer<IVertex>> _boundVertexBuffers = new();
public VertexArray()
{
GL.CreateVertexArrays(1, out int handle);
Handle = handle;
}
public void BindIndexBuffer(IndexBuffer buffer)
{
GL.VertexArrayElementBuffer(Handle, buffer.Handle);
Log.Debug("Vertex array {Handle} bound to index buffer {Buffer}", Handle, buffer.Handle);
}
public void BindVertexBuffer<T>(VertexBuffer<T> buffer, int bindingIndex = 0, int divisor = 0)
where T : struct, IVertex
{
if (bindingIndex < 0)
throw new ArgumentException("Binding index must be greater than 0");
if (divisor < 0)
throw new ArgumentException("Divisor must be greater than 0");
var stride = Marshal.SizeOf<T>();
var fields = IVertex.GetFields<T>();
GL.VertexArrayVertexBuffer(Handle, bindingIndex, buffer.Handle, 0, stride);
var location = 0;
foreach (var field in fields)
{
var attribute = field.GetCustomAttribute<VertexAttribute>()!;
var offset = Marshal.OffsetOf<T>(field.Name).ToInt32();
SetupAttribute(attribute, location, offset, bindingIndex);
location += attribute.RepeatCount;
}
GL.VertexArrayBindingDivisor(Handle, bindingIndex, divisor);
Log.Debug(
"Vertex array {Handle} bound to vertex buffer {Buffer} at {BindingIndex} binding with {Divisor} divisor",
Handle, buffer.Handle, bindingIndex, divisor);
}
private void SetupAttribute(VertexAttribute attribute, int baseLocation, int baseOffset, int bindingIndex)
{
var size = attribute.ComponentCount * IVertex.AttributeSize(attribute.Type);
for (var i = 0; i < attribute.RepeatCount; i++)
{
var location = baseLocation + i;
var offset = baseOffset + i * size;
GL.EnableVertexArrayAttrib(Handle, location);
GL.VertexArrayAttribFormat(Handle, location, attribute.ComponentCount, attribute.Type, attribute.Normalized,
offset);
GL.VertexArrayAttribBinding(Handle, location, bindingIndex);
}
}
internal override void Bind()
{
GL.BindVertexArray(Handle);
}
internal override void Unbind()
{
GL.BindVertexArray(0);
}
protected override void Destroy()
{
GL.DeleteVertexArray(Handle);
}
}