117 lines
3.1 KiB
C++
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;
|
|
}
|
|
|