diff options
author | pryazha <pryadeiniv@mail.ru> | 2025-06-15 16:07:54 +0500 |
---|---|---|
committer | pryazha <pryadeiniv@mail.ru> | 2025-06-15 16:07:54 +0500 |
commit | f30a4eba44c77d5c743fe9308dc697a3225e8dd8 (patch) | |
tree | c171da2e8d1127409e2ffe9e56e2e027bac48e28 /shader.h | |
parent | 92a8eb610f40c9770569ca63ca1bd705a6d3497d (diff) |
i don't even know
Diffstat (limited to 'shader.h')
-rw-r--r-- | shader.h | 105 |
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); +} |