#include "shader.h" Shader::Shader() { id = 0; uniform_projection = 0; uniform_model = 0; } Shader::~Shader() { clear_shader(this); } bool create_shader(Shader *shader, const char *vertex_shader_path, const char *fragment_shader_path) { string vertex_shader_code = read_entire_file(vertex_shader_path); string fragment_shader_code = read_entire_file(fragment_shader_path); shader->id = glCreateProgram(); if (!shader) { printf("Error creating shader shader!\n"); return false; } { bool success = add_shader(shader, vertex_shader_code.c_str(), VERTEX); if (!success) { printf("Error adding vertex shader"); return false; } } { bool success = add_shader(shader, fragment_shader_code.c_str(), FRAGMENT); if (!success) { printf("Error adding fragment shader"); return false; } } s32 result = 0; s8 errors[1024] = {0}; glLinkProgram(shader->id); glGetProgramiv(shader->id, GL_LINK_STATUS, &result); if (!result) { glGetProgramInfoLog(shader->id, sizeof(errors), NULL, errors); printf("Error linking shader: '%s'\n", errors); return false; } glValidateProgram(shader->id); glGetProgramiv(shader->id, GL_VALIDATE_STATUS, &result); if (!result) { glGetProgramInfoLog(shader->id, sizeof(errors), NULL, errors); printf("Error validating shader: '%s'\n", errors); return false; } shader->uniform_projection = glGetUniformLocation(shader->id, "projection"); shader->uniform_model = glGetUniformLocation(shader->id, "model"); shader->uniform_view = glGetUniformLocation(shader->id, "view"); shader->uniform_eye_position = glGetUniformLocation(shader->id, "eye_position"); shader->uniform_ambient_color = glGetUniformLocation(shader->id, "sun.color"); shader->uniform_ambient_intensity = glGetUniformLocation(shader->id, "sun.ambient_intensity"); shader->uniform_diffuse_direction = glGetUniformLocation(shader->id, "sun.direction"); shader->uniform_diffuse_intensity = glGetUniformLocation(shader->id, "sun.diffuse_intensity"); shader->uniform_shininess = glGetUniformLocation(shader->id, "material.shininess"); shader->uniform_specular_intensity = glGetUniformLocation(shader->id, "material.specular_intensity"); return true; } bool add_shader(Shader *shader, const char *shader_code, Shader_Type shader_type) { u32 _shader = glCreateShader(shader_type); const char *code[1]; code[0] = shader_code; int code_length[1]; code_length[0] = strlen(shader_code); glShaderSource(_shader, 1, code, code_length); glCompileShader(_shader); int result = 0; char errors[1024] = {0}; glGetShaderiv(_shader, GL_COMPILE_STATUS, &result); if (!result) { glGetShaderInfoLog(_shader, sizeof(errors), NULL, errors); printf("Error compiling the %d shader->id: '%s'\n", shader_type, errors); return false; } glAttachShader(shader->id, _shader); return true; } void clear_shader(Shader *shader) { if (shader->id != 0) { glDeleteProgram(shader->id); shader->id = 0; } shader->uniform_model = 0; shader->uniform_projection = 0; }