-
Notifications
You must be signed in to change notification settings - Fork 0
/
Shader.cpp
120 lines (101 loc) · 2.86 KB
/
Shader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "Shader.h"
#include <fstream>
#include <stdexcept>
#include <glm\gtc\type_ptr.hpp>
GLint Shader::activeProgram = 0;
Shader::Shader(const GLchar * vertexPath, const GLchar * fragmentPath)
{
// Create vertex and fragment shader
GLuint vs = loadShader(GL_VERTEX_SHADER, vertexPath);
GLuint fs = loadShader(GL_FRAGMENT_SHADER, fragmentPath);
// Link shader program (connect vs and ps)
program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
}
Shader::Shader(
const GLchar * vertexPath,
const GLchar * fragmentPath,
const GLchar * geometryPath)
: Shader(vertexPath, fragmentPath)
{
// Create geometry shader
GLuint gs = loadShader(GL_GEOMETRY_SHADER, geometryPath);
// attach and link
glAttachShader(program, gs);
glLinkProgram(program);
}
Shader::~Shader()
{
}
void Shader::catchShaderError(GLuint shader, const GLchar * path)
{
GLint success = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (success == GL_FALSE)
{
GLint logSize = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
char *log = new char[logSize];
glGetShaderInfoLog(shader, logSize, &logSize, &log[0]);
throw std::runtime_error(
"shader compile error: " +
std::string(path) + "\n" +
std::string(log));
}
}
GLuint Shader::loadShader(GLenum type, const GLchar * fileName)
{
// Register a new shader
GLuint shader = glCreateShader(type);
// Open shader file and save its content in a string
std::ifstream file(fileName);
std::string fileContent(
(std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
file.close();
// Make a pointer to a cstring
const char* fileContentPtr = fileContent.c_str();
// Load shader code into graphics card and compile it
glShaderSource(shader, 1, &fileContentPtr, nullptr);
glCompileShader(shader);
// Check if any erros occured and handle them
catchShaderError(shader, fileName);
return shader;
}
void Shader::use()
{
glUseProgram(program);
activeProgram = program;
}
GLint Shader::getUniform(const GLchar * name)
{
if (program != activeProgram)
throw std::runtime_error("not the active shader program");
return glGetUniformLocation(program, name);
}
void Shader::setUniform(const GLchar * name, GLfloat value)
{
glUniform1f(getUniform(name), value);
}
void Shader::setUniform(const GLchar * name, const vec2 & vec)
{
glUniform2fv(getUniform(name), 1, value_ptr(vec));
}
void Shader::setUniform(const GLchar * name, const vec3 & vec)
{
glUniform3fv(getUniform(name), 1, value_ptr(vec));
}
void Shader::setUniform(const GLchar * name, const mat4 & mat)
{
glUniformMatrix4fv(getUniform(name), 1, GL_FALSE, value_ptr(mat));
}
void Shader::setUniform(const GLchar * name, GLuint value)
{
glUniform1ui(getUniform(name), value);
}
void Shader::setUniform(const GLchar * name, const uvec2 & vec)
{
glUniform2uiv(getUniform(name), 1, value_ptr(vec));
}