Files
openglplayground/shaders.cc

135 lines
3.1 KiB
C++

#include <glbinding/gl/gl.h>
#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;
}