transparent-cube

Minimal cross-platform native/wasm graphics example.
git clone git://git.amin.space/transparent-cube.git
Log | Files | Refs | README | LICENSE

commit 3d90c9751f31351dbe4f7773edf2436efc3bdea5
parent 14532145b7b19e5fbdd246248118031058b6bc94
Author: amin <dev@aminmesbah.com>
Date:   Wed,  3 Jul 2019 21:11:52 +0000

Don't call glGetUniformLocation every frame

FossilOrigin-Name: 837021952318595c7867a6710ea89efaefe58dcdc06868337c56b52b5189ce18
Diffstat:
Msrc/game.c | 8++++----
Msrc/shader.c | 65+++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Msrc/shader.h | 26+++++++++++++++++++-------
3 files changed, 74 insertions(+), 25 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -104,8 +104,8 @@ void game_update_and_render(struct GameState *game_state, float dt, u32 screen_w glBlendFunc(GL_SRC_ALPHA, GL_CONSTANT_ALPHA); shader_use(&game_state->cube_shader); - shader_setm4(&game_state->cube_shader, "view", &view); - shader_setm4(&game_state->cube_shader, "projection", &projection); + shader_setm4(&game_state->cube_shader, SHADER_UNIFORM_VIEW, &view); + shader_setm4(&game_state->cube_shader, SHADER_UNIFORM_PROJECTION, &projection); m4 model = glmth_m4_init_id(); f32 angle = 20.0f; @@ -116,8 +116,8 @@ void game_update_and_render(struct GameState *game_state, float dt, u32 screen_w model = glmth_rotate(model, rot_rad, glmth_v3_init(0.0f, 0.0f, 1.0f)); f32 alpha = 0.2f * (1.5f + glmth_sinf(0.5f * dt)); - shader_setm4(&game_state->cube_shader, "model", &model); - shader_setf(&game_state->cube_shader, "alpha", alpha); + shader_setm4(&game_state->cube_shader, SHADER_UNIFORM_MODEL, &model); + shader_setf(&game_state->cube_shader, SHADER_UNIFORM_ALPHA, alpha); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); diff --git a/src/shader.c b/src/shader.c @@ -50,6 +50,17 @@ bool shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_s 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) + { + print("Uniform name not found in shader: %s\n", name); + } + compiled_shader->uniform_locations[uniform] = location; + } return true; } } @@ -76,66 +87,92 @@ void shader_use(struct Shader *s) } -void shader_setb(struct Shader *s, char *name, bool value) +void shader_setb(struct Shader *s, enum ShaderUniform u, bool value) { if (shader_check_pointer(s)) { - glUniform1i(glGetUniformLocation(s->program, name), (int)value); + glUniform1i(s->uniform_locations[u], (int)value); } } -void shader_seti(struct Shader *s, char *name, int value) +void shader_seti(struct Shader *s, enum ShaderUniform u, int value) { if (shader_check_pointer(s)) { - glUniform1i(glGetUniformLocation(s->program, name), value); + glUniform1i(s->uniform_locations[u], value); } } -void shader_setf(struct Shader *s, char *name, f32 value) +void shader_setf(struct Shader *s, enum ShaderUniform u, f32 value) { if (shader_check_pointer(s)) { - glUniform1f(glGetUniformLocation(s->program, name), value); + glUniform1f(s->uniform_locations[u], value); } } -void shader_setm4(struct Shader *s, char *name, m4 *mat) +void shader_setm4(struct Shader *s, enum ShaderUniform u, m4 *mat) { if (shader_check_pointer(s)) { f32 valueptr[sizeof(m4)]; glmth_m4_valueptr(*mat, valueptr); - glUniformMatrix4fv(glGetUniformLocation(s->program, name), 1, GL_TRUE, valueptr); + glUniformMatrix4fv(s->uniform_locations[u], 1, GL_TRUE, valueptr); } } -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 (shader_check_pointer(s)) { - glUniform3f(glGetUniformLocation(s->program, name), x, y, z); + glUniform3f(s->uniform_locations[u], x, y, z); } } -void shader_setf3_1(struct Shader *s, char *name, f32 f) +void shader_setf3_1(struct Shader *s, enum ShaderUniform u, f32 f) { if (shader_check_pointer(s)) { - shader_setf3(s, name, f, f, f); + shader_setf3(s, u, f, f, f); } } -void shader_setv3(struct Shader *s, char *name, v3 *v) +void shader_setv3(struct Shader *s, enum ShaderUniform u, v3 *v) { if (shader_check_pointer(s)) { - shader_setf3(s, name, v->x, v->y, v->z); + 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_ALPHA: + name = "alpha"; + 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_ALPHA, + + NUM_SHADER_UNIFORMS, +}; + struct Shader { u32 program; + i32 uniform_locations[NUM_SHADER_UNIFORMS]; }; 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, char *name, bool value); -void shader_seti(struct Shader *s, char *name, int value); -void shader_setf(struct Shader *s, char *name, f32 value); -void shader_setm4(struct Shader *s, char *name, m4 *mat); -void shader_setf3(struct Shader *s, char *name, f32 x, f32 y, f32 z); -void shader_setf3_1(struct Shader *s, char *name, f32 f); -void shader_setv3(struct Shader *s, char *name, v3 *v); +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);