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