-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathShader.cpp
177 lines (143 loc) · 5.05 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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include "Shader.h"
#include "Util.h"
Shader::Shader(const char* vertexCode, const char* fragmentCode)
{
// compile
GLuint vertex, fragment;
int success;
char infoLog[512];
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vertexCode, nullptr);
glCompileShader(vertex);
// catch compile errors
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertex, 512, nullptr, infoLog);
prints("\n\nERROR: Failed to compile vertex shader! Error log:\n"); prints(infoLog); prints("\n\n");
crash();
}
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fragmentCode, nullptr);
glCompileShader(fragment);
// catch compile errors
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertex, 512, nullptr, infoLog);
prints("\n\nERROR: Failed to compile fragment shader! Error log:\n"); prints(infoLog); prints("\n\n");
crash();
}
// create program & attach shaders
ID = glCreateProgram();
glAttachShader(ID, vertex);
glAttachShader(ID, fragment);
glLinkProgram(ID);
// catch linking errors
glGetProgramiv(ID, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(ID, 512, nullptr, infoLog);
prints("\n\nERROR: Failed to link shader program! Error log:\n"); prints(infoLog); prints("\n\n");
crash();
}
// delete the shaders as they're linked into our program now and no longer necessary
glDeleteShader(vertex);
glDeleteShader(fragment);
cacheUniforms();
}
Shader::Shader(const char* computeCode)
{
prints(computeCode);
const GLuint computeShader = glCreateShader(GL_COMPUTE_SHADER);
glShaderSource(computeShader, 1, &computeCode, nullptr);
glCompileShader(computeShader);
// catch errors
int success;
char infoLog[512];
glGetShaderiv(computeShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(computeShader, 512, nullptr, infoLog);
prints("\n\nERROR: Failed to compile compute shader! Error log:\n"); prints(infoLog); prints("\n\n");
crash();
}
// link the program
ID = glCreateProgram();
glAttachShader(ID, computeShader);
glLinkProgram(ID);
// catch errors
glGetProgramiv(ID, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(ID, 512, nullptr, infoLog);
prints("\n\nERROR: Failed to link compute shader! Error log:\n"); prints(infoLog); prints("\n\n");
crash();
}
glDetachShader(ID, computeShader);
glDeleteShader(computeShader);
cacheUniforms();
}
// use/activate the shader
void Shader::use() const {
glUseProgram(ID);
}
// utility uniform functions
void Shader::setBool(const char* name, int len, const bool value) const {
glUniform1i(getUniformLocation(name, len), int(value));
}
// ------------------------------------------------------------------------
void Shader::setInt(const char* name, int len, const int value) const {
glUniform1i(getUniformLocation(name, len), value);
}
// ------------------------------------------------------------------------
void Shader::setFloat(const char* name, int len, const float value) const {
glUniform1f(getUniformLocation(name, len), value);
}
// ------------------------------------------------------------------------
void Shader::setVec2(const char* name, int len, const vec2& value) const
{
glUniform2f(getUniformLocation(name, len), value.x, value.y);
}
void Shader::setVec2(const char* name, int len, const float x, const float y) const
{
glUniform2f(getUniformLocation(name, len), x, y);
}
// ------------------------------------------------------------------------
void Shader::setVec3(const char* name, int len, const vec3& value) const
{
glUniform3f(getUniformLocation(name, len), value.x, value.y, value.z);
}
void Shader::setVec3(const char* name, int len, const float x, const float y, const float z) const
{
glUniform3f(getUniformLocation(name, len), x, y, z);
}
void Shader::cacheUniforms()
{
GLint i;
GLint count; // uniform count
GLint size; // size of the variable
GLenum type; // type of the variable (float, vec3 or mat4, etc)
const GLsizei bufSize = 16; // maximum name length
GLchar name[bufSize]; // variable name in GLSL
GLsizei length; // name length
glGetProgramiv(ID, GL_ACTIVE_UNIFORMS, &count);
//uniformCache.reserve(count);
for (i = 0; i < count; i++)
{
glGetActiveUniform(ID, (GLuint)i, bufSize, &length, &size, &type, name);
uniformCache.push_back(murmurHash2(name, length));
}
}
GLint Shader::getUniformLocation(const char* uniformName, int len) const
{
unsigned int hash = murmurHash2(uniformName, len);
int loc = 0;
for(int loc = 0; loc < uniformCache.size(); loc++)
{
if(uniformCache[loc] == hash)
return loc;
}
prints("ERROR: Can't find uniform "); prints(uniformName); prints("\n");
return 0;
}