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:
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);