udemy_opengl/src/shader.cpp

117 lines
3.1 KiB
C++

#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;
}