adding gfx and ui stuff

This commit is contained in:
Daniel Ledda
2026-06-04 18:22:30 +02:00
parent d676c50961
commit 4dfac3f82f
48 changed files with 26734 additions and 3 deletions

275
gfx/render.c Normal file
View File

@@ -0,0 +1,275 @@
#include "render.h"
static RenderObjects_Char createCharObjects(Arena *arena, size_t count) {
RenderObjects_Char result = {0};
result.count = count;
result.begin.buf = PushFullList(arena, Vec2List, count);
result.glyph.buf = PushFullList(arena, IntList, count);
result.fontSize.buf = PushFullList(arena, FloatList, count);
result.color.buf = PushFullList(arena, Vec4List, count);
glGenVertexArrays(1, &result.vao);
glGenBuffers(1, &result.begin.bufId);
glGenBuffers(1, &result.glyph.bufId);
glGenBuffers(1, &result.fontSize.bufId);
glGenBuffers(1, &result.color.bufId);
glBindVertexArray(result.vao);
int32 bufItemSize = sizeof(result.begin.buf.data[0]);
glBindBuffer(GL_ARRAY_BUFFER, result.begin.bufId);
glBufferData(GL_ARRAY_BUFFER, result.begin.buf.length * bufItemSize, 0, GL_STREAM_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, bufItemSize, NULL);
glVertexAttribDivisor(0, 1);
glEnableVertexAttribArray(0);
bufItemSize = sizeof(result.glyph.buf.data[0]);
glBindBuffer(GL_ARRAY_BUFFER, result.glyph.bufId);
glBufferData(GL_ARRAY_BUFFER, result.glyph.buf.length * bufItemSize, 0, GL_STREAM_DRAW);
glVertexAttribIPointer(1, 1, GL_INT, bufItemSize, NULL);
glVertexAttribDivisor(1, 1);
glEnableVertexAttribArray(1);
bufItemSize = sizeof(result.fontSize.buf.data[0]);
glBindBuffer(GL_ARRAY_BUFFER, result.fontSize.bufId);
glBufferData(GL_ARRAY_BUFFER, result.fontSize.buf.length * bufItemSize, 0, GL_STREAM_DRAW);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, bufItemSize, NULL);
glVertexAttribDivisor(2, 1);
glEnableVertexAttribArray(2);
bufItemSize = sizeof(result.color.buf.data[0]);
glBindBuffer(GL_ARRAY_BUFFER, result.color.bufId);
glBufferData(GL_ARRAY_BUFFER, result.color.buf.length * bufItemSize, 0, GL_STREAM_DRAW);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, bufItemSize, NULL);
glVertexAttribDivisor(3, 1);
glEnableVertexAttribArray(3);
return result;
}
static RenderObjects_Rect createRectangleObjects(Arena *arena, size_t count) {
RenderObjects_Rect result = {0};
result.count = count;
result.p0.buf = PushFullList(arena, Vec2List, count);
result.p1.buf = PushFullList(arena, Vec2List, count);
result.color.buf = PushFullList(arena, Vec4List, count);
result.borderRadius.buf = PushFullList(arena, FloatList, count);
result.borderThickness.buf = PushFullList(arena, FloatList, count);
result.borderColor.buf = PushFullList(arena, Vec4List, count);
result.edgeSoftness.buf = PushFullList(arena, FloatList, count);
glGenVertexArrays(1, &result.vao);
glGenBuffers(1, &result.p0.bufId);
glGenBuffers(1, &result.p1.bufId);
glGenBuffers(1, &result.color.bufId);
glGenBuffers(1, &result.borderRadius.bufId);
glGenBuffers(1, &result.borderThickness.bufId);
glGenBuffers(1, &result.borderColor.bufId);
glGenBuffers(1, &result.edgeSoftness.bufId);
glBindVertexArray(result.vao);
int32 bufItemSize = sizeof(result.p0.buf.data[0]);
glBindBuffer(GL_ARRAY_BUFFER, result.p0.bufId);
glBufferData(GL_ARRAY_BUFFER, result.p0.buf.length * bufItemSize, 0, GL_STREAM_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, bufItemSize, NULL);
glVertexAttribDivisor(0, 1);
glEnableVertexAttribArray(0);
bufItemSize = sizeof(result.p1.buf.data[0]);
glBindBuffer(GL_ARRAY_BUFFER, result.p1.bufId);
glBufferData(GL_ARRAY_BUFFER, result.p1.buf.length * bufItemSize, 0, GL_STREAM_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, bufItemSize, NULL);
glVertexAttribDivisor(1, 1);
glEnableVertexAttribArray(1);
bufItemSize = sizeof(result.color.buf.data[0]);
glBindBuffer(GL_ARRAY_BUFFER, result.color.bufId);
glBufferData(GL_ARRAY_BUFFER, result.color.buf.length * bufItemSize, 0, GL_STREAM_DRAW);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, bufItemSize, NULL);
glVertexAttribDivisor(2, 1);
glEnableVertexAttribArray(2);
bufItemSize = sizeof(result.borderRadius.buf.data[0]);
glBindBuffer(GL_ARRAY_BUFFER, result.borderRadius.bufId);
glBufferData(GL_ARRAY_BUFFER, result.borderRadius.buf.length * bufItemSize, 0, GL_STREAM_DRAW);
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, bufItemSize, NULL);
glVertexAttribDivisor(3, 1);
glEnableVertexAttribArray(3);
bufItemSize = sizeof(result.borderThickness.buf.data[0]);
glBindBuffer(GL_ARRAY_BUFFER, result.borderThickness.bufId);
glBufferData(GL_ARRAY_BUFFER, result.borderThickness.buf.length * bufItemSize, 0, GL_STREAM_DRAW);
glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, bufItemSize, NULL);
glVertexAttribDivisor(4, 1);
glEnableVertexAttribArray(4);
bufItemSize = sizeof(result.borderColor.buf.data[0]);
glBindBuffer(GL_ARRAY_BUFFER, result.borderColor.bufId);
glBufferData(GL_ARRAY_BUFFER, result.borderColor.buf.length * bufItemSize, 0, GL_STREAM_DRAW);
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, bufItemSize, NULL);
glVertexAttribDivisor(5, 1);
glEnableVertexAttribArray(5);
bufItemSize = sizeof(result.edgeSoftness.buf.data[0]);
glBindBuffer(GL_ARRAY_BUFFER, result.edgeSoftness.bufId);
glBufferData(GL_ARRAY_BUFFER, result.edgeSoftness.buf.length * bufItemSize, 0, GL_STREAM_DRAW);
glVertexAttribPointer(6, 1, GL_FLOAT, GL_FALSE, bufItemSize, NULL);
glVertexAttribDivisor(6, 1);
glEnableVertexAttribArray(6);
return result;
}
#define GL_UpdateBuffer(buffer) \
glBindBuffer(GL_ARRAY_BUFFER, (buffer).bufId);\
glBufferSubData(GL_ARRAY_BUFFER, 0, (buffer).buf.length * sizeof((buffer).underlying), (buffer).buf.data);
static void updateCharObjectBuffers(Renderer *r) {
glBindVertexArray(r->chars.vao);
GL_UpdateBuffer(r->chars.begin);
GL_UpdateBuffer(r->chars.glyph);
GL_UpdateBuffer(r->chars.fontSize);
GL_UpdateBuffer(r->chars.color);
}
static void updateRectangleObjectBuffers(Renderer *r) {
glBindVertexArray(r->rects.vao);
GL_UpdateBuffer(r->rects.p0);
GL_UpdateBuffer(r->rects.p1);
GL_UpdateBuffer(r->rects.color);
GL_UpdateBuffer(r->rects.borderRadius);
GL_UpdateBuffer(r->rects.borderThickness);
GL_UpdateBuffer(r->rects.borderColor);
GL_UpdateBuffer(r->rects.edgeSoftness);
}
Renderer createRenderer(Arena *arena, Scene *scene, Camera *cam, int32 light) {
return (Renderer){
.scene = scene,
.light = light,
.camera = cam,
.rects = createRectangleObjects(arena, 1024),
.chars = createCharObjects(arena, 10000),
};
}
void renderBegin(Renderer *r) {
r->rects.p0.buf.length = 0;
r->rects.p1.buf.length = 0;
r->rects.color.buf.length = 0;
r->rects.borderRadius.buf.length = 0;
r->rects.borderThickness.buf.length = 0;
r->rects.borderColor.buf.length = 0;
r->rects.edgeSoftness.buf.length = 0;
r->chars.begin.buf.length = 0;
r->chars.glyph.buf.length = 0;
r->chars.fontSize.buf.length = 0;
r->chars.color.buf.length = 0;
r->sceneWidth = 0;
r->sceneHeight = 0;
r->sceneX = 0;
r->sceneY = 0;
}
#define CHECK() do{ GLenum e=glGetError(); if(e) printf("GL err 0x%x at %s:%d\n",e,__FILE__,__LINE__); }while(0)
void renderEnd(Renderer *r) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
// --- 3D Scene ---
glViewport(r->sceneX, r->height - r->sceneY - r->sceneHeight, r->sceneWidth, r->sceneHeight);
cameraSetAspect(r->camera, r->sceneWidth, r->sceneHeight);
glUseProgram(r->phongShader->progId);
setUniformMat4fv(r->phongShader, "projection", &r->camera->proj);
setUniformMat4fv(r->phongShader, "view", &r->camera->view);
SceneGraphNode *lightGraphNode = getSceneGraphNode(r->scene, r->light);
setUniform3fv(r->phongShader, "light_pos", &lightGraphNode->translation);
setUniform3fv(r->phongShader, "camera", &r->camera->pos);
//glBindVertexArray(r->cubeMesh->vao);
int model_uniform = getUniformLocation(r->phongShader, "model");
int solid_color_uniform = getUniformLocation(r->phongShader, "solid_color");
for (EachIn(r->scene->entities, i)) {
Entity *entity = &r->scene->entities.data[i];
if (entity->flags & EntityFlags_Render && entity->flags & EntityFlags_Visible) {
setUniform4fvByLoc(solid_color_uniform, &entity->color);
setUniformMat4fvByLoc(model_uniform, &getSceneGraphNode(r->scene, entity->graphNodeHandle)->world);
glBindTexture(GL_TEXTURE_2D, entity->tex->tex_id);
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity->mesh->num_indices);
entity->flags &= ~EntityFlags_Render;
}
}
// --- UI overlay ---
glViewport(0, 0, r->width, r->height);
glUseProgram(r->solidShader->progId);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Matrix ortho = MatrixOrtho(0.0, r->width, r->height, 0.0, -1.0, 1.0);
// - 1. Rects
updateRectangleObjectBuffers(r);
setUniformMat4fv(r->solidShader, "projection", &ortho);
glBindVertexArray(r->rects.vao);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, r->rects.p0.buf.length);
// - 2. Text
updateCharObjectBuffers(r);
glUseProgram(r->textShader->progId);
setUniformMat4fv(r->textShader, "projection", &ortho);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, r->activeFont->texId);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER, r->activeFont->glyphTableTexId);
setUniform1i(r->textShader, "glyph_table", 1);
glBindVertexArray(r->chars.vao);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, r->chars.begin.buf.length);
glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
}
void rendererPlaceRectangle(Renderer *r, real32 x, real32 y, real32 width, real32 height, Vec4 color, real32 borderRadius, real32 borderThickness, Vec4 borderColor) {
x = roundf(x);
y = roundf(y);
width = roundf(width);
height = roundf(height);
ListAppend(r->rects.p0.buf, ((Vec2){ x, y }));
ListAppend(r->rects.p1.buf, ((Vec2){ x + width, y + height }));
ListAppend(r->rects.color.buf, color);
ListAppend(r->rects.borderRadius.buf, borderRadius);
ListAppend(r->rects.borderThickness.buf, borderThickness);
ListAppend(r->rects.borderColor.buf, borderColor);
ListAppend(r->rects.edgeSoftness.buf, 0.15f);
}
void rendererPlaceString(Renderer *r, string s, real32 x, real32 y, Vec4 color, real32 fontSize) {
real32 ratio = fontSize / r->activeFont->lineHeight;
real32 charWidth = ratio * r->activeFont->charWidth;
for (int i = 0; i < s.length; i++) {
ListAppend(r->chars.begin.buf, ((Vec2){ .x=x + i*charWidth, .y=y }));
ListAppend(r->chars.glyph.buf, s.str[i] - 32);
ListAppend(r->chars.fontSize.buf, ratio);
ListAppend(r->chars.color.buf, (color));
}
}