summaryrefslogtreecommitdiff
path: root/shader.h
diff options
context:
space:
mode:
Diffstat (limited to 'shader.h')
-rw-r--r--shader.h105
1 files changed, 105 insertions, 0 deletions
diff --git a/shader.h b/shader.h
new file mode 100644
index 0000000..189225a
--- /dev/null
+++ b/shader.h
@@ -0,0 +1,105 @@
+shader_t compile_gl_shader(u32 type, char **src)
+{
+ shader_t shader = {0};
+ shader.id = glCreateShader(type);
+ glShaderSource(shader.id, 1, (const char **)src, 0);
+ glCompileShader(shader.id);
+
+ i32 status;
+ glGetShaderiv(shader.id, GL_COMPILE_STATUS, &status);
+ if (status == GL_FALSE)
+ glGetShaderInfoLog(shader.id, MAX_SHADER_LOG, 0, shader.log);
+ else
+ snprintf(shader.log, MAX_SHADER_LOG, "compiled successfully");
+
+ return shader;
+}
+
+shader_t compile_gl_shader_file(u32 type, const char *filename)
+{
+ char *src;
+ shader_t shader = {0};
+
+ arena_t tmp = alloc_arena(0);
+ if (!sys_read_file(&tmp, &src, filename)) {
+ printf("error: failed to read: \"%s\"\n", filename);
+ release_arena(&tmp);
+ return shader;
+ }
+ shader = compile_gl_shader(type, &src);
+ release_arena(&tmp);
+
+ if (!shader.id)
+ printf("error: \"%s\": ", filename);
+ else
+ printf("info: \"%s\": ", filename);
+ printf("%s", shader.log);
+ printf("\n");
+
+ return shader;
+}
+
+shader_t load_gl_shader(const char *dir, const char *vert_filename, const char *geom_filename, const char *frag_filename)
+{
+ shader_t shader = {0};
+ shader.id = glCreateProgram();
+
+ char full_path[MAX_PATH];
+ shader_t vert;
+ if (vert_filename) {
+ snprintf(full_path, sizeof(full_path), "%s/%s", dir, vert_filename);
+ vert = compile_gl_shader_file(GL_VERTEX_SHADER, full_path);
+ glAttachShader(shader.id, vert.id);
+ }
+
+ shader_t geom;
+ if (geom_filename) {
+ snprintf(full_path, sizeof(full_path), "%s/%s", dir, geom_filename);
+ geom = compile_gl_shader_file(GL_GEOMETRY_SHADER, full_path);
+ glAttachShader(shader.id, geom.id);
+ }
+
+ shader_t frag;
+ if (frag_filename) {
+ snprintf(full_path, sizeof(full_path), "%s/%s", dir, frag_filename);
+ frag = compile_gl_shader_file(GL_FRAGMENT_SHADER, full_path);
+ glAttachShader(shader.id, frag.id);
+ }
+
+ i32 status;
+ glLinkProgram(shader.id);
+ glGetProgramiv(shader.id, GL_LINK_STATUS, &status);
+ if (status == GL_FALSE) {
+ glGetProgramInfoLog(shader.id, MAX_SHADER_LOG, 0, shader.log);
+ printf("error: failed to link shader program:\n%s", shader.log);
+ } else {
+ printf("info: shader linked successfuly\n\n");
+ }
+
+ if (vert_filename)
+ glDeleteShader(vert.id);
+ if (geom_filename)
+ glDeleteShader(geom.id);
+ if (frag_filename)
+ glDeleteShader(frag.id);
+
+ return shader;
+}
+
+void shader_set_v3(shader_t shader, const char *name, v3 vec)
+{
+ i32 location = glGetUniformLocation(shader.id, name);
+ glUniform3fv(location, 1, (f32 *)&vec);
+}
+
+void shader_set_v4(shader_t shader, const char *name, v4 vec)
+{
+ i32 location = glGetUniformLocation(shader.id, name);
+ glUniform4fv(location, 1, (f32 *)&vec);
+}
+
+void shader_set_mat4(shader_t shader, const char *name, mat4 mat)
+{
+ i32 location = glGetUniformLocation(shader.id, name);
+ glUniformMatrix4fv(location, 1, 0, (f32 *)&mat);
+}