From 07116cd28845c3e589ab7e99f32d0ab96dd5cf4d Mon Sep 17 00:00:00 2001 From: onelin Date: Sat, 29 Nov 2025 23:04:52 +0100 Subject: TMP Rework rendering --- src/rendering.c | 350 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 223 insertions(+), 127 deletions(-) (limited to 'src/rendering.c') diff --git a/src/rendering.c b/src/rendering.c index 76df988..8f7104e 100644 --- a/src/rendering.c +++ b/src/rendering.c @@ -1,4 +1,3 @@ -#include #include #include @@ -11,16 +10,12 @@ #include #include #include +#include /* Extern globals */ extern Instance* GLOBAL_PLATFORM; -/* Globals */ -#define drawcall_limit (64 * 1024) -RenderDrawCall drawcalls[drawcall_limit]; -i32 drawcall_len = 0; - usize ShaderBufferDataType_size(u16 flags) { const ShaderBufferFlag t = ShaderBuffer_get_data_type(flags); @@ -441,114 +436,62 @@ void render_begin(Window* w) { ((GladGLContext*)(w->context))->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -void render_present(Window* w) { - /* This is GL specific, TODO: move the GL-specific code elsewhere. Maybe make - * this whole present GL specific? assign it as a fn ptr in the Window struct? */ - GladGLContext *restrict gl = w->context; - Camera c = *GLOBAL_PLATFORM->cam; - - mat4 view; // view - vec3 angle; // viewing angle / direction of the camera - mat4 camera_matrix; - - glm_vec3_sub(c.pos, c.dir, angle); - glm_lookat(c.pos, angle, GLM_YUP, view); - glm_mat4_mul(c.per, view, camera_matrix); - - for (i32 drawcall_idx = 0; drawcall_idx < drawcall_len; drawcall_idx++) { - RenderDrawCall dc = drawcalls[drawcall_idx]; - - // bind shader program - // - set uniforms - // bind vertex array - // bind index buffer - - - const RenderObject* const restrict o = dc.model; - vec3 pos; - glm_vec3_copy(dc.pos, pos); - - gl->UseProgram(o->shader.program); - // TODO: Use texture atlas - gl->BindTextureUnit(0, o->texture); - - { - mat4 model = GLM_MAT4_IDENTITY_INIT; - mat4 modelviewprojection; - - model[3][0] = pos[0]; - model[3][1] = pos[1]; - model[3][2] = pos[2]; - - // modelviewprojection = p * view * model - glm_mat4_mul(model, camera_matrix, modelviewprojection); - - // TODO: Do this only once during initialization - gl->UniformMatrix4fv(o->mvp, 1, GL_FALSE, &modelviewprojection[0][0]); - gl->UniformMatrix4fv(o->model_position, 1, GL_FALSE, &model[0][0]); - } - - // TODO the buffers need to be abstracted a bit more - gl->BindVertexArray(o->vao); - - ShaderBuffer* ibo = NULL; - for (usize i = 0; i < o->buffer_len; i++) { - const u32 b_gl_type = ShaderBuffer_get_gl_type(o->buffer[i].buffertype); - if (b_gl_type == GL_ELEMENT_ARRAY_BUFFER) { - ibo = &o->buffer[i]; - } - - gl->EnableVertexAttribArray((u32)i); - gl->BindBuffer(b_gl_type, o->buffer[i].buffername); - gl->VertexAttribPointer( - // index of the attribute - (u32)i, - // number of component - (i32)o->buffer[i].components, - // type - ShaderBuffer_get_gl_datatype(o->buffer[i].buffertype), - // normalized? - GL_FALSE, - // stride - 0, - // array buffer offset - (void*)0 - ); - } - - // Draw the model ! - const i32 sz = (i32)(o->buffer->count * o->buffer->size_elem); - if (ibo) { - gl->DrawElements( - GL_TRIANGLES, - (i32)ibo->count, - ShaderBuffer_get_gl_datatype(ibo->buffertype), - (void*)0 - ); - } else { - // Starting from vertex 0; 3 vertices total -> 1 triangle - gl->DrawArrays(GL_TRIANGLES, 0, sz); +void render_present(Window* w, RenderObject *restrict default_quad) { + const GladGLContext *restrict gl = w->context; + gl->UseProgram(default_quad->shader.program); + gl->BindTextureUnit(0, default_quad->texture); + gl->BindVertexArray(default_quad->vao); + + ShaderBuffer* ibo = NULL; + for (usize i = 0; i < default_quad->buffer_len; i++) { + const u32 b_gl_type = ShaderBuffer_get_gl_type(default_quad->buffer[i].buffertype); + if (b_gl_type == GL_ELEMENT_ARRAY_BUFFER) { + ibo = &default_quad->buffer[i]; } - for (u32 i = 0; i < o->buffer_len; i++) { - gl->DisableVertexAttribArray(i); - } - - gl->BindVertexArray(0); - - //if (i == 8) { - // printf("\r obj: %.3f", (double)(get_time() - t) * 1000.); - //} - } - - drawcall_len = 0; + gl->EnableVertexAttribArray((u32)i); + gl->BindBuffer(b_gl_type, default_quad->buffer[i].buffername); + gl->VertexAttribPointer( + // index of the attribute + (u32)i, + // number of component + (i32)default_quad->buffer[i].components, + // type + ShaderBuffer_get_gl_datatype(default_quad->buffer[i].buffertype), + // normalized? + GL_FALSE, + // stride + 0, + // array buffer offset + (void*)0 + ); + } + + // Draw the model ! + const i32 sz = (i32)(default_quad->buffer->count * default_quad->buffer->size_elem); + if (ibo) { + gl->DrawElements( + GL_TRIANGLES, + (i32)ibo->count, + ShaderBuffer_get_gl_datatype(ibo->buffertype), + (void*)0 + ); + } else { + // Starting from vertex 0; 3 vertices total -> 1 triangle + gl->DrawArrays(GL_TRIANGLES, 0, sz); + } + + for (u32 i = 0; i < default_quad->buffer_len; i++) { + gl->DisableVertexAttribArray(i); + } + + gl->BindVertexArray(0); glfwSwapBuffers(w->window); } void window_reset_drawing(void) { - drawcall_len = 0; - memset(drawcalls, 0, sizeof(RenderDrawCall) * drawcall_limit); + // Clear } void r_perspective(Camera *c, f32 fov, ivec2 windowsize) { @@ -569,10 +512,12 @@ void r_perspective_ortho(Camera *c, f32 sz, ivec2 windowsize) { glm_ortho(-sz * ratio, sz * ratio, -sz, sz, -sz * 10.f, sz * 10.f, c->per); } -void r_set_camera(Camera* c) { - GLOBAL_PLATFORM->cam = c; -} +void r_set_camera(RenderTargets *restrict t, i32 framebuffer_idx, Camera *restrict c) { + ASSERT(t != NULL); + ASSERT(framebuffer_idx == -1 || framebuffer_idx < (i32)t->framebuffer_len); + t->cam[framebuffer_idx] = c; +} void r_reset_camera(Camera* c, ivec2 windowsize) { if (c->type == Camera_Perspective) { @@ -584,19 +529,92 @@ void r_reset_camera(Camera* c, ivec2 windowsize) { } -void engine_draw_model(RenderObject* o, vec4 pos) { - if (drawcall_len + 1 >= drawcall_limit) return; -#ifdef _DEBUG - if (o == NULL) __asm__("int3;"); -#endif - RenderDrawCall dc = { - .model = o, - .scale = pos[3], - }; +void r_draw_model(void *restrict context, RenderTargets *restrict t, u32 framebuffer_idx, RenderObject* o, vec4 pos) { + ASSERT(context != NULL); + ASSERT(t != NULL); + ASSERT(t->framebuffer != NULL); + ASSERT(t->cam != NULL); + ASSERT(t->cam[framebuffer_idx] != NULL); + + const GladGLContext *restrict gl = context; + Camera c = *t->cam[framebuffer_idx]; + //const f32 s = pos[3]; + + mat4 view; // view + vec3 angle; // viewing angle / direction of the camera + mat4 camera_matrix; + + glm_vec3_sub(c.pos, c.dir, angle); + glm_lookat(c.pos, angle, GLM_YUP, view); + glm_mat4_mul(c.per, view, camera_matrix); + + gl->UseProgram(o->shader.program); + // ENUMERATE FRAMEBUFFER TEXTURES + gl->BindTextureUnit(0, o->texture); - glm_vec3_copy(pos, dc.pos); + { + mat4 model = GLM_MAT4_IDENTITY_INIT; + mat4 modelviewprojection; - drawcalls[drawcall_len++] = dc; + model[3][0] = pos[0]; + model[3][1] = pos[1]; + model[3][2] = pos[2]; + + // modelviewprojection = p * view * model + glm_mat4_mul(model, camera_matrix, modelviewprojection); + + // TODO: Do this only once during initialization + gl->UniformMatrix4fv(o->mvp, 1, GL_FALSE, &modelviewprojection[0][0]); + gl->UniformMatrix4fv(o->model_position, 1, GL_FALSE, &model[0][0]); + } + + // TODO the buffers need to be abstracted a bit more + gl->BindVertexArray(o->vao); + + ShaderBuffer* ibo = NULL; + for (usize i = 0; i < o->buffer_len; i++) { + const u32 b_gl_type = ShaderBuffer_get_gl_type(o->buffer[i].buffertype); + if (b_gl_type == GL_ELEMENT_ARRAY_BUFFER) { + ibo = &o->buffer[i]; + } + + gl->EnableVertexAttribArray((u32)i); + gl->BindBuffer(b_gl_type, o->buffer[i].buffername); + gl->VertexAttribPointer( + // index of the attribute + (u32)i, + // number of component + (i32)o->buffer[i].components, + // type + ShaderBuffer_get_gl_datatype(o->buffer[i].buffertype), + // normalized? + GL_FALSE, + // stride + 0, + // array buffer offset + (void*)0 + ); + } + + // Draw the model ! + const i32 sz = (i32)(o->buffer->count * o->buffer->size_elem); + if (ibo) { + gl->DrawElements( + GL_TRIANGLES, + (i32)ibo->count, + ShaderBuffer_get_gl_datatype(ibo->buffertype), + (void*)0 + ); + } else { + // Starting from vertex 0; 3 vertices total -> 1 triangle + gl->DrawArrays(GL_TRIANGLES, 0, sz); + } + + for (u32 i = 0; i < o->buffer_len; i++) { + gl->DisableVertexAttribArray(i); + } + + gl->BindVertexArray(0); } @@ -691,22 +709,100 @@ void r_destroy_framebuffers(void* restrict ctx, u32* restrict framebuffer_array, } void r_create_textures(void* restrict ctx, u32* restrict texture_array, - u32* restrict texture_types, - ivec4* restrict texture_size, usize num_targets) { + u32* restrict texture_parameters, + ivec3* restrict texture_size, usize num_targets) { const GladGLContext* gl = (GladGLContext*)ctx; - gl->CreateTextures(GL_TEXTURE_2D, num_targets, texture_array); + u32 texture_dim = BUFFERPARAMETER_TEXTURE_GET_DIMENSION(texture_parameters[0]); + u32 texture_format = BUFFERPARAMETER_TEXTURE_GET_DIMENSION(texture_parameters[0]); + u32 gl_texture_format; + u32 err; + + for (usize i = 1; i < num_targets; i++) { + ASSERT(texture_dim == BUFFERPARAMETER_TEXTURE_GET_DIMENSION(texture_parameters[i])); + ASSERT(texture_format == BUFFERPARAMETER_TEXTURE_GET_FORMAT(texture_parameters[i])); + } + + switch (texture_format) { + case BUFFERPARAMETER_TEXTURE_FMT_RGBA8: gl_texture_format = GL_RGBA8; break; + case BUFFERPARAMETER_TEXTURE_FMT_SRGB8: gl_texture_format = GL_SRGB; break; + case BUFFERPARAMETER_TEXTURE_FMT_SRGBA8: gl_texture_format = GL_SRGB8_ALPHA8; break; + default: + ERROR("Failed to convert format to GL internal format!"); + exit(EXIT_FAILURE); + } + + // Convert the texturetype to GL texturetype + switch (texture_dim) { + case BUFFERPARAMETER_TEXTURE_1D: + gl->CreateTextures(GL_TEXTURE_1D, num_targets, texture_array); + for (usize i = 0; i < num_targets; i++) { + gl->TextureStorage1D(texture_array[i], 1, gl_texture_format, *texture_size[0]); + } + break; + + case BUFFERPARAMETER_TEXTURE_2D: + gl->CreateTextures(GL_TEXTURE_2D, num_targets, texture_array); + for (usize i = 0; i < num_targets; i++) { + gl->TextureStorage2D(texture_array[i], 1, gl_texture_format, *texture_size[0], *texture_size[1]); + } + break; + + case BUFFERPARAMETER_TEXTURE_3D: + gl->CreateTextures(GL_TEXTURE_3D, num_targets, texture_array); + for (usize i = 0; i < num_targets; i++) { + gl->TextureStorage3D(texture_array[i], 1, gl_texture_format, *texture_size[0], *texture_size[1], *texture_size[2]); + } + break; + + case BUFFERPARAMETER_TEXTURE_4D: + ERROR("4D textures are unsupported!"); + exit(EXIT_FAILURE); + default: + ERROR("Failed to convert dimensionality to GL_TEXTURE_XD"); + exit(EXIT_FAILURE); + } + err = gl->GetError(); + + if (err) { + ERROR("Failed to create textures!"); + } + + // This should probably be changed in the future for (usize i = 0; i < num_targets; i++) { - ASSERT("SWITCH CASE ON BUFFER DIMENSIONALITY"); - ASSERT("SWITCH CASE ON TEXTURE DATA TYPE"); - gl->TextureStorage2D(texture_array[i], 1, texture_types[i], *texture_size[0], *texture_size[1]); gl->TextureParameteri(texture_array[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TextureParameteri(texture_array[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST); } + + err = gl->GetError(); + + if (err) { + ERROR("Failed to set texture parameters!"); + } } void r_destroy_textures(void *restrict ctx, u32* textures, usize num_textures) { const GladGLContext* gl = (GladGLContext*)ctx; gl->DeleteTextures(num_textures, textures); } + +void r_attach_buffers(void *restrict ctx, u32 fbo, u32* buffers, u32* buffer_parameters, i32 num_buffers) { + const GladGLContext *restrict gl = (GladGLContext*)ctx; + + u32 err; + + for (i32 i = 0; i < num_buffers; i++) { + BufferType t = BUFFERPARAMETER_GET_TYPE(buffer_parameters[i]); + + if (t != BufferType_texture) UNIMPLEMENTED; + + // TODO: FINISH ME + gl->NamedFramebufferTexture(fbo, GL_COLOR_ATTACHMENT0 + i, buffers[i], 0); + + err = gl->GetError(); + if (err) { + ERROR("Failed to attach buffer!"); + } + } +} -- cgit v1.3