diff options
Diffstat (limited to 'shader.cpp')
-rw-r--r-- | shader.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/shader.cpp b/shader.cpp new file mode 100644 index 0000000..a0509ff --- /dev/null +++ b/shader.cpp @@ -0,0 +1,93 @@ +#include <fstream> +#include <stdexcept> + +#include <boost/format.hpp> + +#include "shader.h" + +static void gl_check_error(const char *msg) { + GLenum error = glGetError(); + if(error != GL_NO_ERROR) { + throw(std::runtime_error((boost::format("%s:\n%s") % msg % gluErrorString(error)).str())); + } +} + +void GLBaseShader::shader_source(const char *filename) { + std::ifstream inf(filename, std::ios_base::in); + if(!inf.is_open()) { + throw(std::runtime_error((boost::format("Failed to load shader from file %s") % filename).str())); + } + inf.seekg(0, std::ios_base::end); + int length = inf.tellg(); + inf.seekg(0, std::ios_base::beg); + char *buffer = new char[length]; + inf.read(buffer, length); + inf.close(); + + glShaderSource(shader, 1, (const GLchar**)&buffer, &length); + gl_check_error("Failed to set shader source"); + delete[] buffer; + glCompileShader(shader); + int p; + glGetShaderiv(shader, GL_COMPILE_STATUS, &p); + if(p == 0) { + char log[0xffff]; + int size; + glGetShaderInfoLog(shader, 0xffff, &size, (GLchar*)&log); + throw(std::runtime_error((boost::format("Failed to compile shader:\n%s") % log).str())); + } +} + +void GLBaseShader::shader_source(std::string& filename) { + shader_source(filename.c_str()); +} + +GLBaseShader::GLBaseShader(GLenum type) { + shader = glCreateShader(type); +} + +GLBaseShader::~GLBaseShader() { + glDeleteShader(shader); +} + +/** + * GLShaderProgram + */ +GLShaderProgram::GLShaderProgram() { + program = glCreateProgram(); +} + +GLShaderProgram::~GLShaderProgram() { + glDeleteProgram(program); +} + +void GLShaderProgram::attach(GLBaseShader& shader) { + glAttachShader(program, shader.shader); + + gl_check_error("Failed to attach shader to program"); +} + +void GLShaderProgram::detach(GLBaseShader& shader) { + glDetachShader(program, shader.shader); + + gl_check_error("Failed to detach shader from program"); +} + +void GLShaderProgram::link() { + glLinkProgram(program); + + int p; + glGetProgramiv(program, GL_LINK_STATUS, &p); + if(p == 0) { + char log[0xffff]; + int size; + glGetProgramInfoLog(program, 0xffff, &size, (GLchar*)&log); + throw(std::runtime_error((boost::format("Failed to link program:\n%s") % log).str())); + } +} + +void GLShaderProgram::use() { + glUseProgram(program); + + gl_check_error("Failed to use program"); +} |