63 lines
1.6 KiB
C#
63 lines
1.6 KiB
C#
using System.Runtime.InteropServices;
|
|
using Engine.Renderer.Buffer.Vertex;
|
|
using OpenTK.Graphics.OpenGL;
|
|
using Serilog;
|
|
|
|
namespace Engine.Renderer.Buffer;
|
|
|
|
public class VertexBuffer<T> : OpenGlObject
|
|
where T : struct, IVertex
|
|
{
|
|
internal int Count { get; }
|
|
|
|
private readonly int _stride = Marshal.SizeOf<T>();
|
|
|
|
public VertexBuffer(int count, BufferStorageFlags flags)
|
|
{
|
|
if (!IVertex.IsValid(typeof(T)))
|
|
throw new ArgumentException($"Type {typeof(T).Name} is not a valid vertex type");
|
|
|
|
if (count <= 0)
|
|
throw new ArgumentException("Count must be greater than 0");
|
|
|
|
Count = count;
|
|
|
|
GL.CreateBuffers(1, out int handle);
|
|
Handle = handle;
|
|
|
|
GL.NamedBufferStorage(Handle, Count * _stride, IntPtr.Zero, flags);
|
|
|
|
Log.Debug("Vertex buffer {Handle} created with {Count} elements of type {Type}", Handle, Count, typeof(T).Name);
|
|
}
|
|
|
|
public void UploadData(T[] data)
|
|
{
|
|
UploadData(0, data);
|
|
}
|
|
|
|
public void UploadData(int offset, T[] data)
|
|
{
|
|
if (offset < 0)
|
|
throw new ArgumentException("Offset must be greater than 0");
|
|
|
|
if (data.Length + offset > Count)
|
|
throw new ArgumentException("Data array is too large");
|
|
|
|
GL.NamedBufferSubData(Handle, offset * _stride, data.Length * _stride, data);
|
|
}
|
|
|
|
internal override void Bind()
|
|
{
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, Handle);
|
|
}
|
|
|
|
internal override void Unbind()
|
|
{
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
|
}
|
|
|
|
protected override void Destroy()
|
|
{
|
|
GL.DeleteBuffer(Handle);
|
|
}
|
|
} |