#include #include "shaders.hh" using namespace gl; ShaderException::ShaderException(std::string const& msg) : GLException(glGetError()), _msg(msg) { } Shader::Shader(std::string const& program, GLenum type) : _shaderID(glCreateShader(type)) { const char* const arr[] = {program.c_str()}; glShaderSource(_shaderID, 1, arr, NULL); glCompileShader(_shaderID); int state; glGetShaderiv(_shaderID, GL_COMPILE_STATUS, &state); if (state == 0) { int logLength; glGetShaderiv(_shaderID, GL_INFO_LOG_LENGTH, &logLength); char *log = new char[logLength]; glGetShaderInfoLog(_shaderID, logLength, NULL, log); std::string msg(log); delete[] log; glDeleteShader(_shaderID); throw ShaderException(msg); } } Shader::~Shader() { glDeleteShader(_shaderID); } Program::Program(VertexShader& vertex, FragmentShader& frag) : _geom(nullptr), _vertex(vertex), _frag(frag), _progID(glCreateProgram()) { glAttachShader(_progID, _vertex.getID()); glAttachShader(_progID, _frag.getID()); glLinkProgram(_progID); int state; glGetProgramiv(_progID, GL_LINK_STATUS, &state); if (state == 0) { int logLength; glGetProgramiv(_progID, GL_INFO_LOG_LENGTH, &logLength); char *log = new char[logLength]; glGetProgramInfoLog(_progID, logLength, NULL, log); std::string msg(log); delete[] log; glDeleteProgram(_progID); throw ShaderException(msg); } glDetachShader(_progID, _vertex.getID()); glDetachShader(_progID, _frag.getID()); } Program::Program(GeometryShader& geom, VertexShader& vertex, FragmentShader& frag) : _geom(&geom), _vertex(vertex), _frag(frag), _progID(glCreateProgram()) { glAttachShader(_progID, _geom->getID()); glAttachShader(_progID, _vertex.getID()); glAttachShader(_progID, _frag.getID()); glLinkProgram(_progID); int state; glGetProgramiv(_progID, GL_LINK_STATUS, &state); if (!state) { int logLength; glGetProgramiv(_progID, GL_INFO_LOG_LENGTH, &logLength); char *log = new char[logLength]; glGetProgramInfoLog(_progID, logLength, NULL, log); std::string msg(log); delete[] log; glDeleteProgram(_progID); throw ShaderException(msg); } glDetachShader(_progID, _geom->getID()); glDetachShader(_progID, _vertex.getID()); glDetachShader(_progID, _frag.getID()); } Program::~Program() { glDeleteProgram(_progID); } void Program::use() const { glUseProgram(_progID); } GLint Program::getUniformLocation(std::string const& name) const { auto search = _uniformLocCache.find(name); if (search != _uniformLocCache.end()) return search->second; GLint ret = glGetUniformLocation(_progID, name.c_str()); if (ret != -1) _uniformLocCache.emplace(name, ret); return ret; } // GLint Program::getAttribLocation(std::string const& name) const // { // auto search = _attribLocCache.find(name); // if (search != _attribLocCache.end()) // return search->second; // GLint ret = glGetAttribLocation(_progID, name.c_str()); // if (ret != -1) // _attribLocCache.emplace(name, ret); // return ret; // }