a-game

2D platformer written from scratch.
git clone git://git.amin.space/a-game.git
Log | Files | Refs | README | LICENSE

commit a0e9824657d278530015246bc9e9f2d7571d93da
parent 9e0f64d682d43394ff86099f78871abf20b9a872
Author: amin <dev@aminmesbah.com>
Date:   Wed,  3 Jul 2019 21:21:52 +0000

Don't call glGetUniformLocation every frame

The locations don't change after a shader is linked.

FossilOrigin-Name: 455daaff650b39749e5a508527a4ccba95a5118c0e83d2546a20db93ba0d2800
Diffstat:
Msrc/render.c | 8++++----
Msrc/shader.c | 132++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/shader.h | 30+++++++++++++++++++++---------
3 files changed, 99 insertions(+), 71 deletions(-)

diff --git a/src/render.c b/src/render.c @@ -63,8 +63,8 @@ internal void renderer_jobs_draw(struct RendererState *renderer) #endif shader_use(&renderer->shader); - shader_setm4(&renderer->shader, "projection", &renderer->projection); - shader_setm4(&renderer->shader, "view", &renderer->view); + shader_setm4(&renderer->shader, SHADER_UNIFORM_PROJECTION, &renderer->projection); + shader_setm4(&renderer->shader, SHADER_UNIFORM_VIEW, &renderer->view); GLuint current_ebo = renderer->quad_ebo; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, current_ebo); @@ -76,8 +76,8 @@ internal void renderer_jobs_draw(struct RendererState *renderer) current_ebo = j.ebo; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, current_ebo); } - shader_setv3(&renderer->shader, "color", &j.color); - shader_setm4(&renderer->shader, "model", &j.model); + shader_setv3(&renderer->shader, SHADER_UNIFORM_COLOR, &j.color); + shader_setm4(&renderer->shader, SHADER_UNIFORM_MODEL, &j.model); if (j.ebo == renderer->quad_ebo) { glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); diff --git a/src/shader.c b/src/shader.c @@ -1,14 +1,12 @@ bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source, struct Shader *compiled_shader) { - bool compilation_successful = true; GLint success; GLchar info_log[512]; if (!(vertex_shader_source && fragment_shader_source)) { printf("Error: One or more shader source files weren't loaded.\n"); - // TODO: handle errors here in a better way - compilation_successful = false; + return false; } else { @@ -21,7 +19,7 @@ bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_s glGetShaderInfoLog(vertex_shader, 512, NULL, info_log); printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n %s\n", info_log); // TODO: handle errors here in a better way - compilation_successful = false; + return false; } GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); @@ -33,7 +31,7 @@ bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_s glGetShaderInfoLog(fragment_shader, 512, NULL, info_log); printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n %s\n", info_log); // TODO: handle errors here in a better way - compilation_successful = false; + return false; } compiled_shader->program = glCreateProgram(); @@ -46,117 +44,135 @@ bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_s glGetShaderInfoLog(compiled_shader->program, 512, NULL, info_log); printf("ERROR::SHADER::LINKING_FAILED\n %s\n", info_log); // TODO: handle errors here in a better way - compilation_successful = false; + return false; } glDeleteShader(fragment_shader); glDeleteShader(vertex_shader); + + for (u32 uniform = 0; uniform < NUM_SHADER_UNIFORMS; uniform++) + { + char *name = shader_uniform_get_name(uniform); + assert(name); + i32 location = glGetUniformLocation(compiled_shader->program, name); + if (location == -1) + { + printf("Uniform name not found in shader: %s\n", name); + } + compiled_shader->uniform_locations[uniform] = location; + } + return true; } - return compilation_successful; } - -internal void shader_use(struct Shader *s) +bool shader_check_pointer(struct Shader *s) { if (s) { - glUseProgram(s->program); + return true; } else { printf("Error: invalid Shader pointer\n"); + return false; } } - -internal void shader_setb(struct Shader *s, char *name, bool value) +void shader_use(struct Shader *s) { - if (s) - { - glUniform1i(glGetUniformLocation(s->program, name), (int)value); - } - else + if (shader_check_pointer(s)) { - printf("Error: invalid Shader pointer\n"); + glUseProgram(s->program); } } -internal void shader_seti(struct Shader *s, char *name, int value) +void shader_setb(struct Shader *s, enum ShaderUniform u, bool value) { - if (s) - { - glUniform1i(glGetUniformLocation(s->program, name), value); - } - else + if (shader_check_pointer(s)) { - printf("Error: invalid Shader pointer\n"); + glUniform1i(s->uniform_locations[u], (int)value); } } -internal void shader_setf(struct Shader *s, char *name, f32 value) +void shader_seti(struct Shader *s, enum ShaderUniform u, int value) { - if (s) + if (shader_check_pointer(s)) { - glUniform1f(glGetUniformLocation(s->program, name), value); + glUniform1i(s->uniform_locations[u], value); } - else +} + + +void shader_setf(struct Shader *s, enum ShaderUniform u, f32 value) +{ + if (shader_check_pointer(s)) { - printf("Error: invalid Shader pointer\n"); + glUniform1f(s->uniform_locations[u], value); } } -internal void shader_setm4(struct Shader *s, char *name, m4 *mat) +void shader_setm4(struct Shader *s, enum ShaderUniform u, m4 *mat) { - if (s) + if (shader_check_pointer(s)) { f32 valueptr[sizeof(m4)]; math_m4_valueptr(*mat, valueptr); - glUniformMatrix4fv(glGetUniformLocation(s->program, name), 1, GL_TRUE, valueptr); - } - else - { - printf("Error: invalid Shader pointer\n"); + glUniformMatrix4fv(s->uniform_locations[u], 1, GL_TRUE, valueptr); } } -internal void shader_setf3(struct Shader *s, char *name, f32 x, f32 y, f32 z) +void shader_setf3(struct Shader *s, enum ShaderUniform u, f32 x, f32 y, f32 z) { - if (s) + if (shader_check_pointer(s)) { - glUniform3f(glGetUniformLocation(s->program, name), x, y, z); - } - else - { - printf("Error: invalid Shader pointer\n"); + glUniform3f(s->uniform_locations[u], x, y, z); } } -internal void shader_setf3_1(struct Shader *s, char *name, f32 f) +void shader_setf3_1(struct Shader *s, enum ShaderUniform u, f32 f) { - if (s) + if (shader_check_pointer(s)) { - shader_setf3(s, name, f, f, f); - } - else - { - printf("Error: invalid Shader pointer\n"); + shader_setf3(s, u, f, f, f); } } -internal void shader_setv3(struct Shader *s, char *name, v3 *v) +void shader_setv3(struct Shader *s, enum ShaderUniform u, v3 *v) { - if (s) + if (shader_check_pointer(s)) { - shader_setf3(s, name, v->x, v->y, v->z); - } - else - { - printf("Error: invalid Shader pointer\n"); + shader_setf3(s, u, v->x, v->y, v->z); } } + +char *shader_uniform_get_name(enum ShaderUniform u) +{ + char *name = NULL; + switch(u) + { + case SHADER_UNIFORM_MODEL: + name = "model"; + break; + case SHADER_UNIFORM_VIEW: + name = "view"; + break; + case SHADER_UNIFORM_PROJECTION: + name = "projection"; + break; + case SHADER_UNIFORM_COLOR: + name = "color"; + break; + case NUM_SHADER_UNIFORMS: + // fallthrough + default: + // do nothing + break; + } + return name; +} diff --git a/src/shader.h b/src/shader.h @@ -1,14 +1,26 @@ +enum ShaderUniform +{ + SHADER_UNIFORM_MODEL, + SHADER_UNIFORM_VIEW, + SHADER_UNIFORM_PROJECTION, + SHADER_UNIFORM_COLOR, + + NUM_SHADER_UNIFORMS, +}; + struct Shader { u32 program; + i32 uniform_locations[NUM_SHADER_UNIFORMS]; }; -internal bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source, struct Shader *compiled_shader); -internal void shader_use(struct Shader *s); -internal void shader_setb(struct Shader *s, char *name, bool value); -internal void shader_seti(struct Shader *s, char *name, int value); -internal void shader_setf(struct Shader *s, char *name, f32 value); -internal void shader_setm4(struct Shader *s, char *name, m4 *mat); -internal void shader_setf3(struct Shader *s, char *name, f32 x, f32 y, f32 z); -internal void shader_setf3_1(struct Shader *s, char *name, f32 f); -internal void shader_setv3(struct Shader *s, char *name, v3 *v); +bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source, struct Shader *compiled_shader); +void shader_use(struct Shader *s); +void shader_setb(struct Shader *s, enum ShaderUniform u, bool value); +void shader_seti(struct Shader *s, enum ShaderUniform u, int value); +void shader_setf(struct Shader *s, enum ShaderUniform u, f32 value); +void shader_setm4(struct Shader *s, enum ShaderUniform u, m4 *mat); +void shader_setf3(struct Shader *s, enum ShaderUniform u, f32 x, f32 y, f32 z); +void shader_setf3_1(struct Shader *s, enum ShaderUniform u, f32 f); +void shader_setv3(struct Shader *s, enum ShaderUniform u, v3 *v); +char *shader_uniform_get_name(enum ShaderUniform u);