#include #include #include #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"); }