]> git.localhorst.tv Git - tacos.git/blob - src/graphics/shader.cpp
the usual suspects
[tacos.git] / src / graphics / shader.cpp
1 #include "shader.hpp"
2
3 #include "../app/error.hpp"
4
5 #include <algorithm>
6 #include <memory>
7 #include <GL/glew.h>
8 #include <glm/gtc/type_ptr.hpp>
9
10
11 namespace tacos {
12
13 Shader Shader::Vertex(const GLchar *source) {
14         return Shader(GL_VERTEX_SHADER, source);
15 }
16
17 Shader Shader::Fragment(const GLchar *source) {
18         return Shader(GL_FRAGMENT_SHADER, source);
19 }
20
21 Shader::Shader(GLenum type, const GLchar *source)
22 : shader(glCreateShader(type)) {
23         if (shader == 0) {
24                 throw GLError("glCreateShader");
25         }
26         const GLchar *sources[] = { source };
27         glShaderSource(shader, 1, sources, nullptr);
28         glCompileShader(shader);
29         GLint compiled = GL_FALSE;
30         glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
31         if (compiled != GL_TRUE) {
32                 int log_length = 0, max_length = 0;
33                 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &max_length);
34                 ++max_length;
35                 std::unique_ptr<char[]> log(new char[max_length]);
36                 glGetShaderInfoLog(shader, max_length, &log_length, log.get());
37                 log[log_length] = '\0';
38                 glDeleteShader(shader);
39                 throw GLCompileError("glCompileShader", log.get());
40         }
41 }
42
43 Shader::~Shader() noexcept {
44         if (shader != 0) {
45                 glDeleteShader(shader);
46         }
47 }
48
49 Shader::Shader(Shader &&other) noexcept
50 : shader(other.shader) {
51         other.shader = 0;
52 }
53
54 Shader &Shader::operator =(Shader &&other) noexcept {
55         std::swap(shader, other.shader);
56         return *this;
57 }
58
59
60 Program::Program()
61 : program(glCreateProgram()) {
62         if (program == 0) {
63                 throw GLError("glCreateProgram");
64         }
65 }
66
67 Program::~Program() noexcept {
68         glDeleteProgram(program);
69 }
70
71 void Program::Attach(const Shader &shader) noexcept {
72         glAttachShader(program, shader.shader);
73 }
74
75 void Program::Link() {
76         glLinkProgram(program);
77         GLint linked = GL_FALSE;
78         glGetProgramiv(program, GL_LINK_STATUS, &linked);
79         if (linked != GL_TRUE) {
80                 int log_length = 0, max_length = 0;
81                 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &max_length);
82                 ++max_length;
83                 std::unique_ptr<char[]> log(new char[max_length]);
84                 glGetProgramInfoLog(program, max_length, &log_length, log.get());
85                 log[log_length] = '\0';
86                 throw GLCompileError("glLinkProgram", log.get());
87         }
88 }
89
90 void Program::Use() noexcept {
91         glUseProgram(program);
92 }
93
94 GLint Program::AttributeLocation(const GLchar *name) const noexcept {
95         return glGetAttribLocation(program, name);
96 }
97
98 GLint Program::UniformLocation(const GLchar *name) const noexcept {
99         return glGetUniformLocation(program, name);
100 }
101
102 void Program::Uniform(GLint loc, GLint val) noexcept {
103         glUniform1i(loc, val);
104 }
105
106 void Program::Uniform(GLint loc, float val) noexcept {
107         glUniform1f(loc, val);
108 }
109
110 void Program::Uniform(GLint loc, const glm::vec3 &val) noexcept {
111         glUniform3fv(loc, 1, glm::value_ptr(val));
112 }
113
114 void Program::Uniform(GLint loc, const glm::vec4 &val) noexcept {
115         glUniform4fv(loc, 1, glm::value_ptr(val));
116 }
117
118 void Program::Uniform(GLint loc, const glm::mat4 &val) noexcept {
119         glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(val));
120 }
121
122 }