diff options
Diffstat (limited to '')
-rw-r--r-- | src/shader.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/shader.c b/src/shader.c new file mode 100644 index 0000000..7e1b58f --- /dev/null +++ b/src/shader.c @@ -0,0 +1,121 @@ +#include "shader.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +static char *read_file(const char *file_path) { + FILE *file = fopen(file_path, "r"); + if (!file) { + printf("Failed to open file: %s\n", file_path); + return NULL; + } + + fseek(file, 0, SEEK_END); + long file_size = ftell(file); + fseek(file, 0, SEEK_SET); + + char *buffer = (char *)malloc(file_size + 1); + if (!buffer) { + printf("Failed to allocate memory for file: %s\n", file_path); + fclose(file); + return NULL; + } + + fread(buffer, 1, file_size, file); + buffer[file_size] = '\0'; + + fclose(file); + return buffer; +} + +static unsigned int compile_shader(const char *source, GLenum shader_type) { + unsigned int shader = glCreateShader(shader_type); + glShaderSource(shader, 1, &source, NULL); + glCompileShader(shader); + + int success; + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { + char info_log[512]; + glGetShaderInfoLog(shader, 512, NULL, info_log); + printf("Shader compilation failed: %s\n", info_log); + return 0; + } + + return shader; +} + +Shader *shader_create(const char *vertex_path, const char *fragment_path) { + Shader *shader = (Shader *)malloc(sizeof(Shader)); + if (!shader) { + printf("Failed to allocate memory for shader\n"); + return NULL; + } + + char *vertex_source = read_file(vertex_path); + char *fragment_source = read_file(fragment_path); + + if (!vertex_source || !fragment_source) { + free(shader); + free(vertex_source); + free(fragment_source); + return NULL; + } + + unsigned int vertex_shader = compile_shader(vertex_source, GL_VERTEX_SHADER); + unsigned int fragment_shader = + compile_shader(fragment_source, GL_FRAGMENT_SHADER); + + free(vertex_source); + free(fragment_source); + + if (!vertex_shader || !fragment_shader) { + free(shader); + return NULL; + } + + shader->program = glCreateProgram(); + glAttachShader(shader->program, vertex_shader); + glAttachShader(shader->program, fragment_shader); + glLinkProgram(shader->program); + + int success; + glGetProgramiv(shader->program, GL_LINK_STATUS, &success); + if (!success) { + char info_log[512]; + glGetProgramInfoLog(shader->program, 512, NULL, info_log); + printf("Shader program linking failed: %s\n", info_log); + free(shader); + return NULL; + } + + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + + return shader; +} + +void shader_use(Shader *shader) { glUseProgram(shader->program); } + +void shader_delete(Shader *shader) { + glDeleteProgram(shader->program); + free(shader); +} + +void shader_set_int(Shader *shader, const char *name, int value) { + glUniform1i(glGetUniformLocation(shader->program, name), value); +} + +void shader_set_float(Shader *shader, const char *name, float value) { + glUniform1f(glGetUniformLocation(shader->program, name), value); +} + +void shader_set_vec3(Shader *shader, const char *name, float x, float y, + float z) { + glUniform3f(glGetUniformLocation(shader->program, name), x, y, z); +} + +void shader_set_mat4(Shader *shader, const char *name, const float *value) { + glUniformMatrix4fv(glGetUniformLocation(shader->program, name), 1, GL_FALSE, + value); +} |