mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-05-22 13:05:10 +00:00
121 lines
4.0 KiB
C#
121 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using OpenTK.Graphics.OpenGL;
|
|
using PckStudio.Core.Extensions;
|
|
|
|
namespace PckStudio.Rendering
|
|
{
|
|
public class VertexArray : IDisposable
|
|
{
|
|
private int _id;
|
|
private List<VertexBuffer> _vertexBuffers;
|
|
|
|
public VertexArray()
|
|
{
|
|
_id = GL.GenVertexArray();
|
|
_vertexBuffers = new List<VertexBuffer>();
|
|
}
|
|
|
|
public int AddNewBuffer(VertexBufferLayout layout) => AddBuffer(new VertexBuffer(), layout);
|
|
|
|
public int AddBuffer(VertexBuffer buffer, VertexBufferLayout layout)
|
|
{
|
|
Bind();
|
|
buffer.Bind();
|
|
System.Collections.ObjectModel.ReadOnlyCollection<LayoutElement> elements = layout.GetElements();
|
|
int offset = 0;
|
|
int vertexBufferIndex = 0;
|
|
foreach (LayoutElement element in elements)
|
|
{
|
|
Debug.Assert(element.Size > 0);
|
|
switch (element.Type)
|
|
{
|
|
case ShaderDataType.Float:
|
|
case ShaderDataType.Float2:
|
|
case ShaderDataType.Float3:
|
|
case ShaderDataType.Float4:
|
|
GL.EnableVertexAttribArray(vertexBufferIndex);
|
|
GL.VertexAttribPointer(vertexBufferIndex, element.ComponentCount, VertexAttribPointerType.Float, element.Normalize, layout.GetStride(), offset);
|
|
vertexBufferIndex += 1;
|
|
break;
|
|
case ShaderDataType.Int:
|
|
case ShaderDataType.Int2:
|
|
case ShaderDataType.Int3:
|
|
case ShaderDataType.Int4:
|
|
GL.EnableVertexAttribArray(vertexBufferIndex);
|
|
GL.VertexAttribIPointer(vertexBufferIndex, element.ComponentCount, VertexAttribIntegerType.Int, layout.GetStride(), new IntPtr(offset));
|
|
vertexBufferIndex += 1;
|
|
break;
|
|
case ShaderDataType.Mat2:
|
|
case ShaderDataType.Mat3:
|
|
case ShaderDataType.Mat4:
|
|
{
|
|
int count = element.ComponentCount;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
GL.EnableVertexAttribArray(vertexBufferIndex);
|
|
|
|
GL.VertexAttribPointer(vertexBufferIndex, count, VertexAttribPointerType.Float, element.Normalize, layout.GetStride(), offset + count * i);
|
|
|
|
GL.VertexAttribDivisor(vertexBufferIndex, 1);
|
|
vertexBufferIndex += 1;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
offset += element.Size;
|
|
}
|
|
int index = _vertexBuffers.Count;
|
|
_vertexBuffers.Add(buffer);
|
|
return index;
|
|
}
|
|
|
|
public void Bind()
|
|
{
|
|
GL.BindVertexArray(_id);
|
|
}
|
|
|
|
public void Unbind()
|
|
{
|
|
GL.BindVertexArray(0);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Unbind();
|
|
Clear();
|
|
GL.DeleteVertexArray(_id);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
foreach (VertexBuffer vao in _vertexBuffers)
|
|
{
|
|
vao.Dispose();
|
|
}
|
|
_vertexBuffers.Clear();
|
|
}
|
|
|
|
public void SelectBuffer(int index)
|
|
{
|
|
if (!_vertexBuffers.IndexInRange(index))
|
|
throw new IndexOutOfRangeException(index.ToString());
|
|
Bind();
|
|
GetBuffer(index).Bind();
|
|
}
|
|
|
|
public VertexBuffer GetBuffer(int index)
|
|
{
|
|
if (_vertexBuffers.IndexInRange(index))
|
|
return _vertexBuffers[index];
|
|
throw new IndexOutOfRangeException(index.ToString());
|
|
}
|
|
}
|
|
}
|