From ed544013b57c90bdaff9fc6c2f35997b0023b9c6 Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Wed, 1 Dec 2021 12:49:06 -0500 Subject: [PATCH] remove ShaderArray struct, and add shaders to GLContext --- src/main.cpp | 36 ++++++++------------- src/shader.cpp | 88 +++++++++++++++++++++++++++++++++++++------------- src/shader.h | 23 ++++++------- 3 files changed, 90 insertions(+), 57 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c7a2013..d60ab54 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -114,19 +114,6 @@ getFreeGLMesh(gl_mesh_array* gma) return nullptr; } -ShaderArray* -initShaderArray(memory_arena* arena, u32 count) -{ - ShaderArray* arr = - (ShaderArray*) arenaAllocateBlock(arena, sizeof(ShaderArray)); - arr->max = count; - arr->count = 0; - arr->shaders = (shader_program*) arenaAllocateBlock( - arena, count * sizeof(shader_program)); - - return arr; -} - gl_mesh_array* initGLMeshArray(memory_arena* arena, u32 count) { @@ -140,21 +127,23 @@ initGLMeshArray(memory_arena* arena, u32 count) return gma; } +#define DEFAULT_SHADER_COUNT 64 +#define DEFAULT_UBO_COUNT 32 GLContext* initGLContext(memory_arena* arena) { GLContext* gl_ctx = (GLContext*) arenaAllocateBlock(arena, sizeof(GLContext)); - gl_ctx->shader_arr = initShaderArray(arena, 256); + gl_ctx->max_shaders = DEFAULT_SHADER_COUNT; + gl_ctx->num_shaders = 0; + gl_ctx->shaders = (shader_program*) arenaAllocateBlock( + arena, DEFAULT_SHADER_COUNT * sizeof(shader_program)); + gl_ctx->max_ubos = DEFAULT_UBO_COUNT; + gl_ctx->num_ubos = 0; + gl_ctx->uniform_buffers = (gl_buffer*) arenaAllocateBlock(arena, + gl_ctx->max_ubos * sizeof(gl_buffer)); gl_ctx->binding_count = 0; - // FIXME: why does only binding points work here? - // the other values were accessable after linking a shader maybe? - glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &gl_ctx->max_binding_points); - glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &gl_ctx->max_vertex_blocks); - glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &gl_ctx->max_fragment_blocks); - glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &gl_ctx->max_ublock_size); - return gl_ctx; } @@ -343,7 +332,10 @@ main() return 1; if (rs) { - rs->gl_ctx->xform_ubo = initTransforms(rs->xforms, rs->gl_ctx); + + // FIXME: need to test this with another shader that has another UBO + gl_buffer& ubo = rs->gl_ctx->uniform_buffers[rs->gl_ctx->num_ubos++]; + initTransforms(arena, rs->xforms, &ubo, rs->gl_ctx); if (!addShaderProgram(arena, rs->gl_ctx, diff --git a/src/shader.cpp b/src/shader.cpp index ea81cb4..5cce26c 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -32,13 +32,13 @@ addShaderProgram(memory_arena* arena, const char* fs, const char* name) { - if (gl_ctx->shader_arr->count >= gl_ctx->shader_arr->max) { - std::cout << "ShaderArray full\n"; + if (gl_ctx->num_shaders >= gl_ctx->max_shaders) { + printf("%s(), GLContext->shaders full\n", __FUNCTION__); return false; } - shader_program* s = &gl_ctx->shader_arr->shaders[gl_ctx->shader_arr->count]; - gl_ctx->shader_arr->count++; + shader_program* s = &gl_ctx->shaders[gl_ctx->num_shaders]; + gl_ctx->num_shaders++; u32 name_len = std::strlen(name) + 1; s->name = (char*) arenaAllocateBlock(arena, name_len); @@ -73,6 +73,10 @@ addShaderProgram(memory_arena* arena, glGetProgramiv(s->prog_id, GL_LINK_STATUS, &is_linked); if (is_linked) { + // NOTE: need to set context maximums after at least one shader has + // been linked + initCTXSizes(gl_ctx); + dumpShader(s->prog_id); s->model_xform_id = glGetUniformLocation(s->prog_id, "model_xform"); // FIXME: testing @@ -195,8 +199,19 @@ parseShaderUniforms(memory_arena* arena, shader_program* s, GLContext* gl_ctx) } } -gl_buffer -initTransforms(transforms* xforms, +bool +parseAttributes(memory_arena* arena, shader_program* s, GLContext* gl_ctx) +{ + // TODO: parse buffers (vert, normal, uv), glGetActiveAttrib() + /// + printf("%s(), FIXME:\n", __FUNCTION__); + return true; +} + +void +initTransforms(memory_arena* arena, + transforms* xforms, + gl_buffer* xform_ubo, GLContext* gl_ctx, float fov, float near_clip_plane, @@ -208,22 +223,51 @@ initTransforms(transforms* xforms, xforms->proj_xform = glm::infinitePerspective( glm::radians(fov), aspect_ratio, near_clip_plane); - gl_buffer ubo = {0}; - glGenBuffers(1, &ubo.id); - ubo.target = GL_UNIFORM_BUFFER; - ubo.data_type = GL_FLOAT; - ubo.data_size = sizeof(*xforms); - glBindBuffer(GL_UNIFORM_BUFFER, ubo.id); - glBufferData(GL_UNIFORM_BUFFER, sizeof(*xforms), xforms, GL_DYNAMIC_DRAW); - - // NOTE: need to manually keep track of block bindings - glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &gl_ctx->max_binding_points); - glBindBufferBase(GL_UNIFORM_BUFFER, gl_ctx->binding_count, ubo.id); - ubo.binding_idx = gl_ctx->binding_count; - gl_ctx->binding_count++; - glBindBuffer(GL_UNIFORM_BUFFER, 0); - - return ubo; + glGenBuffers(1, &xform_ubo->id); + xform_ubo->target = GL_UNIFORM_BUFFER; + xform_ubo->data_type = GL_FLOAT; + xform_ubo->data_size = sizeof(*xforms); + + // TODO: make an arenaAddCStr(arena, char*& str_ref) for this nonsense + const char* block_name = "matrices"; + u32 name_len = std::strlen(block_name) + 1; + xform_ubo->name = (char*) arenaAllocateBlock(arena, name_len); + std::strncpy(xform_ubo->name, block_name, name_len); + // END TODO: + + glBindBuffer(xform_ubo->target, xform_ubo->id); + glBufferData(xform_ubo->target, sizeof(*xforms), xforms, + GL_DYNAMIC_DRAW); + // bindbufferbase + xform_ubo->binding_idx = gl_ctx->binding_count++; + glBindBufferBase(xform_ubo->target, xform_ubo->binding_idx, xform_ubo->id); + glBindBuffer(xform_ubo->target, 0); +} + +void +initCTXSizes(GLContext* gl_ctx) +{ + // NOTE: see https://docs.gl/gl3/glGet for other useful context info + if (gl_ctx->max_binding_points == 0) { + glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, + &gl_ctx->max_binding_points); + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &gl_ctx->max_vertex_blocks); + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, + &gl_ctx->max_fragment_blocks); + glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &gl_ctx->max_ublock_size); + +#if 1 + printf("%s(), context size info set\n", __FUNCTION__); + printf("GL_MAX_UNIFORM_BUFFER_BINDINGS: %d\n", + gl_ctx->max_binding_points); + printf("GL_MAX_VERTEX_UNIFORM_BLOCKS: %d\n", + gl_ctx->max_vertex_blocks); + printf("GL_MAX_FRAGMENT_UNIFORM_BLOCKS: %d\n", + gl_ctx->max_fragment_blocks); + printf("GL_MAX_UNIFORM_BLOCK_SIZE: %d\n", + gl_ctx->max_ublock_size); +#endif + } } gl_mesh diff --git a/src/shader.h b/src/shader.h index 35a5c65..e7b0555 100644 --- a/src/shader.h +++ b/src/shader.h @@ -61,26 +61,21 @@ struct shader_program u64 hash; // NOTE: hash of vs filpath + fs filepath concat }; -// TODO: is it a good idea to merge this into GLContext? -struct ShaderArray -{ - u32 count; - u32 max; - shader_program* shaders; -}; - struct GLContext { - gl_buffer xform_ubo; - // TODO: keep an array of uniform buffer objects stored on ctx? - GLuint binding_count; GLint max_binding_points; GLint max_vertex_blocks; GLint max_fragment_blocks; GLint max_ublock_size; - ShaderArray* shader_arr; + u32 max_ubos; + u32 num_ubos; + gl_buffer* uniform_buffers; + + u32 max_shaders; + u32 num_shaders; + shader_program* shaders; }; struct transforms @@ -150,7 +145,9 @@ gl_mesh loadGLMesh(shader_program* s, const mesh& m, GLenum draw_mode, const glm::vec3& pos); -gl_buffer initTransforms(transforms* xforms, +void initTransforms(memory_arena* arena, + transforms* xforms, + gl_buffer* xform_ubo, GLContext* gl_ctx, float fov = DEFAULT_FOV, float near_clip_plane = NEAR_CLIP_PLANE,