Files
voxel/UI/GuiBatcher.cs

86 lines
2.9 KiB
C#

using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
public class GuiBatcher
{
private List<UiVertex> _vertices = new List<UiVertex>();
private int _vbo;
private int _vao;
public GuiBatcher()
{
_vao = GL.GenVertexArray();
_vbo = GL.GenBuffer();
GL.BindVertexArray(_vao);
GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo);
// Position (2 floats)
GL.EnableVertexAttribArray(0);
GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 8 * sizeof(float), 0);
// TexCoord (2 floats)
GL.EnableVertexAttribArray(1);
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 8 * sizeof(float), 2 * sizeof(float));
// Color (4 floats)
GL.EnableVertexAttribArray(2);
GL.VertexAttribPointer(2, 4, VertexAttribPointerType.Float, false, 8 * sizeof(float), 4 * sizeof(float));
}
public void DrawQuad(float x, float y, float w, float h, Vector4 uv, Vector4 color)
{
// Two triangles (Standard Minecraft Blit)
_vertices.Add(new UiVertex(x, y, uv.X, uv.Y, color)); // TL
_vertices.Add(new UiVertex(x + w, y, uv.Z, uv.Y, color)); // TR
_vertices.Add(new UiVertex(x, y + h, uv.X, uv.W, color)); // BL
_vertices.Add(new UiVertex(x + w, y, uv.Z, uv.Y, color)); // TR
_vertices.Add(new UiVertex(x + w, y + h, uv.Z, uv.W, color)); // BR
_vertices.Add(new UiVertex(x, y + h, uv.X, uv.W, color)); // BL
}
public void Render()
{
if (_vertices.Count == 0) return;
GL.BindVertexArray(_vao);
GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo);
var data = _vertices.ToArray();
GL.BufferData(BufferTarget.ArrayBuffer, data.Length * 8 * sizeof(float), data, BufferUsageHint.StreamDraw);
GL.DrawArrays(PrimitiveType.Triangles, 0, _vertices.Count);
_vertices.Clear(); // Reset for next frame
}
public void DrawString(string text, float x, float y, float size, Vector4 color)
{
float charStep = 1.0f / 16.0f;
float currentX = x;
foreach (char c in text)
{
int ascii = (int)c;
int row = ascii / 16;
int col = ascii % 16;
float uStart = col * charStep;
float uEnd = uStart + charStep;
float vStart = 1.0f - (row * charStep);
float vEnd = vStart - charStep;
Vector4 uv = new Vector4(
uStart, // U start
vStart, // V start
uEnd, // U end
vEnd // V end
);
DrawQuad(currentX, y, size, size, uv, color);
float charWidthPixels = (CharWidth.GetWidth(c) + 1) / 8;
float charWidthWorldUnits = size * charWidthPixels;
currentX += charWidthWorldUnits;
}
}
}