#include "shader.h" #include #include #include 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); }