From 39cc17db686b9e02394510442ed388b4097d6bdb Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Thu, 10 Feb 2022 18:28:01 -0500 Subject: [PATCH] remove fixed properties of ShaderProgram in favor of dynamic properties this makes use of our dynamic shader parsing code, so we don't need to track these properties explicitly any more. --- src/shader.cpp | 47 ++++++++++++++++++++++++++++++++++++++--------- src/shader.h | 20 ++++++++++++++++---- src/tangerine.h | 1 + 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/shader.cpp b/src/shader.cpp index 32b1e3f..242d928 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -102,9 +102,6 @@ addShaderProgram(MemoryArena* arena, GLuint vs_id, fs_id; if (compileAndLinkShader(s, v_str, f_str, vs_id, fs_id)) { - s->node_xform_id = glGetUniformLocation(s->prog_id, "node_xform"); - // TODO: add sampler uniform detection in dynamic shader parsing - s->sampler_id = glGetUniformLocation(s->prog_id, "sampler"); glDetachShader(s->prog_id, vs_id); glDetachShader(s->prog_id, fs_id); glDeleteShader(vs_id); @@ -239,12 +236,21 @@ renderVAO(GLMesh* glmesh, { glUseProgram(shader->prog_id); glBindVertexArray(glmesh->vao_id); - glUniformMatrix4fv(shader->node_xform_id, 1, GL_FALSE, - (float*) node_xform); - if (glmesh->has_texture) { - glBindTexture(GL_TEXTURE_2D, gl_tex->id); - glUniform1i(shader->sampler_id, 0); + for (u32 i = 0; i < shader->num_uniforms; i++) { + const GLUniform& uniform = shader->uniforms[i]; + + if (uniform.uniform_type == UNIFORM_NODE_XFORM) { + glUniformMatrix4fv(uniform.location, 1, GL_FALSE, + (float*) node_xform); + } + + else if (glmesh->has_texture && + uniform.uniform_type == UNIFORM_SAMPLER) + { + glBindTexture(GL_TEXTURE_2D, gl_tex->id); + glUniform1i(uniform.location, 0); + } } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glmesh->element_buf->id); @@ -519,6 +525,27 @@ getGLTypeSizeStd140(GLenum e) } } +UniformType +getUniformType(const char* name) +{ + if (utilCStrMatch(name, "sampler")) + return UNIFORM_SAMPLER; + else if (utilCStrMatch(name, "node_xform")) + return UNIFORM_NODE_XFORM; + else if (utilCStrMatch(name, "normal_xform")) + return UNIFORM_NORMAL_XFORM; + else if (utilCStrMatch(name, "view_xform")) + return UNIFORM_VIEW_XFORM; + else if (utilCStrMatch(name, "proj_xform")) + return UNIFORM_PROJECTION_XFORM; + else if (utilCStrMatch(name, "matrices")) + return UNIFORM_BLOCK_XFORMS; + else if (utilCStrMatch(name, "lights")) + return UNIFORM_BLOCK_LIGHTS; + else + return UNIFORM_UNKNOWN; +} + const GLUniform parseUniform(MemoryArena* arena, ShaderProgram* s, u32 uniform_idx) { @@ -532,7 +559,7 @@ parseUniform(MemoryArena* arena, ShaderProgram* s, u32 uniform_idx) sizeof(unif_name), &name_len, &unif.num_elements, - &unif.uniform_type, + &unif.gl_type, unif_name); glGetActiveUniformsiv(s->prog_id, 1, &uniform_idx, GL_UNIFORM_BLOCK_INDEX, @@ -543,6 +570,7 @@ parseUniform(MemoryArena* arena, ShaderProgram* s, u32 uniform_idx) &unif.uniform_offset); unif.name = arenaCopyCStr(arena, unif_name); + unif.uniform_type = getUniformType(unif.name); unif.location = glGetUniformLocation(s->prog_id, unif.name); return unif; @@ -635,6 +663,7 @@ parseUniformBlocks(MemoryArena* arena, ShaderProgram* s, GLContext* gl_ctx) glGetActiveUniformBlockName( s->prog_id, i, 256, &name_len, block_name); ub.name = arenaCopyCStr(arena, block_name); + ub.uniform_type = getUniformType(ub.name); glGetActiveUniformBlockiv(s->prog_id, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, (GLint*) &ub.num_uniforms); diff --git a/src/shader.h b/src/shader.h index 8978003..0561a67 100644 --- a/src/shader.h +++ b/src/shader.h @@ -9,6 +9,19 @@ #include "util.h" +enum UniformType +{ + UNIFORM_SAMPLER, + UNIFORM_NODE_XFORM, + UNIFORM_VIEW_XFORM, + UNIFORM_PROJECTION_XFORM, + UNIFORM_NORMAL_XFORM, + UNIFORM_BLOCK_XFORMS, + UNIFORM_BLOCK_LIGHTS, + UNIFORM_UNKNOWN, + UNIFORM_TYPE_COUNT +}; + struct GLUniform { // NOTE: would be nice to use idx as the location parameter because it seems @@ -17,7 +30,8 @@ struct GLUniform GLuint idx; GLint location; GLint block_idx; - GLenum uniform_type; // NOTE: GL_UNSIGNED_INT, GL_FLOAT_VEC4 + UniformType uniform_type; + GLenum gl_type; // NOTE: GL_UNSIGNED_INT, GL_FLOAT_VEC4 GLint num_elements; // NOTE: 1 unless uniform is an array of base types GLint array_stride; // NOTE: bytes between array elements GLint uniform_offset; // NOTE: byte offset from beginning of uniform @@ -28,6 +42,7 @@ struct GLUniformBlock { GLuint block_id; GLint binding_idx; + UniformType uniform_type; GLuint num_uniforms; GLUniform* uniforms; char* name; @@ -65,9 +80,6 @@ struct GLBufferToAttribMapping struct ShaderProgram { GLuint prog_id; - GLuint xforms_ubo_id; - GLuint node_xform_id; - GLint sampler_id; u32 num_blocks; GLUniformBlock* uniform_blocks; diff --git a/src/tangerine.h b/src/tangerine.h index b52e052..f20f136 100644 --- a/src/tangerine.h +++ b/src/tangerine.h @@ -58,6 +58,7 @@ * - need a separate GLBufferToAttribMapping for each mesh on an entity * - maybe fixed now with MeshBufferType enum and getMeshData() * - allow entities to have an empty diffuse texture (see initEntity()) +* - use dynamic shader parsing to set 'sampler_id' for shaders with textures */