X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fgraphics%2Fshader.cpp;fp=src%2Fgraphics%2Fshader.cpp;h=b82a6c8dc18e5c4986115ebde21ffb4b181fb192;hb=88073614253d3a9c678848a6e905c3794aa831ca;hp=0000000000000000000000000000000000000000;hpb=918ede5e89fb34dc13760501576545e991196056;p=tacos.git diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp new file mode 100644 index 0000000..b82a6c8 --- /dev/null +++ b/src/graphics/shader.cpp @@ -0,0 +1,122 @@ +#include "shader.hpp" + +#include "../app/error.hpp" + +#include +#include +#include +#include + + +namespace tacos { + +Shader Shader::Vertex(const GLchar *source) { + return Shader(GL_VERTEX_SHADER, source); +} + +Shader Shader::Fragment(const GLchar *source) { + return Shader(GL_FRAGMENT_SHADER, source); +} + +Shader::Shader(GLenum type, const GLchar *source) +: shader(glCreateShader(type)) { + if (shader == 0) { + throw GLError("glCreateShader"); + } + const GLchar *sources[] = { source }; + glShaderSource(shader, 1, sources, nullptr); + glCompileShader(shader); + GLint compiled = GL_FALSE; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (compiled != GL_TRUE) { + int log_length = 0, max_length = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &max_length); + ++max_length; + std::unique_ptr log(new char[max_length]); + glGetShaderInfoLog(shader, max_length, &log_length, log.get()); + log[log_length] = '\0'; + glDeleteShader(shader); + throw GLCompileError("glCompileShader", log.get()); + } +} + +Shader::~Shader() noexcept { + if (shader != 0) { + glDeleteShader(shader); + } +} + +Shader::Shader(Shader &&other) noexcept +: shader(other.shader) { + other.shader = 0; +} + +Shader &Shader::operator =(Shader &&other) noexcept { + std::swap(shader, other.shader); + return *this; +} + + +Program::Program() +: program(glCreateProgram()) { + if (program == 0) { + throw GLError("glCreateProgram"); + } +} + +Program::~Program() noexcept { + glDeleteProgram(program); +} + +void Program::Attach(const Shader &shader) noexcept { + glAttachShader(program, shader.shader); +} + +void Program::Link() { + glLinkProgram(program); + GLint linked = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linked); + if (linked != GL_TRUE) { + int log_length = 0, max_length = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &max_length); + ++max_length; + std::unique_ptr log(new char[max_length]); + glGetProgramInfoLog(program, max_length, &log_length, log.get()); + log[log_length] = '\0'; + throw GLCompileError("glLinkProgram", log.get()); + } +} + +void Program::Use() noexcept { + glUseProgram(program); +} + +GLint Program::AttributeLocation(const GLchar *name) const noexcept { + return glGetAttribLocation(program, name); +} + +GLint Program::UniformLocation(const GLchar *name) const noexcept { + return glGetUniformLocation(program, name); +} + +void Program::Uniform(GLint loc, GLint val) noexcept { + glUniform1i(loc, val); +} + +void Program::Uniform(GLint loc, float val) noexcept { + glUniform1f(loc, val); +} + +void Program::Uniform(GLint loc, const glm::vec3 &val) noexcept { + glUniform3fv(loc, 1, glm::value_ptr(val)); +} + +void Program::Uniform(GLint loc, const glm::vec4 &val) noexcept { + glUniform4fv(loc, 1, glm::value_ptr(val)); +} + +void Program::Uniform(GLint loc, const glm::mat4 &val) noexcept { + glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(val)); +} + +}