mirror of
https://github.com/Relintai/programming_tutorials.git
synced 2025-05-11 22:52:11 +02:00
128 lines
2.8 KiB
C++
128 lines
2.8 KiB
C++
#include "shader.h"
|
|
|
|
#include <stdio.h>
|
|
#include <vector>
|
|
|
|
Shader *Shader::current_shader = nullptr;
|
|
|
|
bool Shader::bind() {
|
|
if (current_shader != this) {
|
|
glUseProgram(program);
|
|
|
|
current_shader = this;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
void Shader::unbind() {
|
|
if (current_shader == this) {
|
|
glUseProgram(0);
|
|
}
|
|
}
|
|
|
|
void Shader::compile() {
|
|
program = glCreateProgram();
|
|
|
|
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
const GLchar **vertex_shader_source = get_vertex_shader_source();
|
|
|
|
glShaderSource(vertex_shader, 1, vertex_shader_source, NULL);
|
|
glCompileShader(vertex_shader);
|
|
|
|
GLint shader_compiled = GL_FALSE;
|
|
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &shader_compiled);
|
|
if (shader_compiled != GL_TRUE) {
|
|
print_shader_errors(vertex_shader, "compiling Vertex Shader");
|
|
return;
|
|
}
|
|
|
|
glAttachShader(program, vertex_shader);
|
|
|
|
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
const GLchar **fragment_shader_source = get_fragment_shader_source();
|
|
|
|
glShaderSource(fragment_shader, 1, fragment_shader_source, NULL);
|
|
glCompileShader(fragment_shader);
|
|
|
|
GLint fragment_shader_compiled = GL_FALSE;
|
|
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &fragment_shader_compiled);
|
|
if (fragment_shader_compiled != GL_TRUE) {
|
|
print_shader_errors(fragment_shader, "compiling Fragment Shader");
|
|
return;
|
|
}
|
|
|
|
glAttachShader(program, fragment_shader);
|
|
|
|
glLinkProgram(program);
|
|
|
|
GLint program_success = GL_TRUE;
|
|
glGetProgramiv(program, GL_LINK_STATUS, &program_success);
|
|
if (program_success != GL_TRUE) {
|
|
print_shader_errors(program, "linking Shader program");
|
|
return;
|
|
}
|
|
}
|
|
void Shader::destroy() {
|
|
glDeleteShader(vertex_shader);
|
|
glDeleteShader(fragment_shader);
|
|
glDeleteProgram(program);
|
|
}
|
|
|
|
const GLchar **Shader::get_vertex_shader_source() {
|
|
return vertex_shader_source;
|
|
}
|
|
void Shader::set_vertex_shader_source(const GLchar **source) {
|
|
vertex_shader_source = source;
|
|
}
|
|
|
|
const GLchar **Shader::get_fragment_shader_source() {
|
|
return fragment_shader_source;
|
|
}
|
|
void Shader::set_fragment_shader_source(const GLchar **source) {
|
|
fragment_shader_source = source;
|
|
}
|
|
|
|
void Shader::print_shader_errors(const GLuint p_program, const char *name) {
|
|
int max_length = 5000;
|
|
std::vector<GLchar> error_log(max_length);
|
|
glGetShaderInfoLog(p_program, max_length, &max_length, &error_log[0]);
|
|
|
|
printf("Error %s!\n", name);
|
|
printf("%s\n", &error_log[0]);
|
|
}
|
|
|
|
Shader::Shader() {
|
|
}
|
|
Shader::~Shader() {
|
|
destroy();
|
|
}
|
|
|
|
//Meyers singleton
|
|
//Thread safe
|
|
ShaderCache *ShaderCache::get_singleton() {
|
|
static ShaderCache instance;
|
|
|
|
return &instance;
|
|
}
|
|
|
|
Shader *ShaderCache::get_shader(const int id) {
|
|
return shaders[id];
|
|
}
|
|
void ShaderCache::add_shader(const int id, Shader *shader) {
|
|
shaders[id] = shader;
|
|
}
|
|
|
|
ShaderCache::ShaderCache() {
|
|
}
|
|
ShaderCache::~ShaderCache() {
|
|
for (const std::pair<int, Shader*>& n : shaders) {
|
|
delete n.second;
|
|
}
|
|
|
|
shaders.clear();
|
|
}
|