-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGLSLProgram.cpp
More file actions
154 lines (123 loc) · 3.72 KB
/
GLSLProgram.cpp
File metadata and controls
154 lines (123 loc) · 3.72 KB
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
#include "GLSLProgram.h"
#include "Errors.h"
#include <fstream>
#include <vector>
GLSLProgram::GLSLProgram() :
_shaderProgramID(0),
_vertShaderID(0),
_fragShaderID(0)
{
}
GLSLProgram::~GLSLProgram()
{
}
void GLSLProgram::compileShaders(const std::string& vertPath, const std::string& fragPath)
{
_vertShaderID = glCreateShader(GL_VERTEX_SHADER);
if (!_vertShaderID)
{
fatalError("Could not create vertex shader.");
}
_fragShaderID = glCreateShader(GL_FRAGMENT_SHADER);
if (!_fragShaderID)
{
fatalError("Could not create fragment shader.");
}
compileShader(_vertShaderID, vertPath);
compileShader(_fragShaderID, fragPath);
}
std::string GLSLProgram::readShaderFile(const std::string& filePath)
{
std::ifstream fileStream(filePath);
if (fileStream.fail())
{
perror(filePath.c_str());
fatalError("Failed to open" + filePath + ".");
}
std::string fileContents = "";
std::string line;
while (std::getline(fileStream, line))
{
fileContents += line + "\n";
}
fileStream.close();
return fileContents;
}
void GLSLProgram::compileShader(GLuint shaderID, const std::string& filePath)
{
// Read contents of shader file
std::string shaderData = readShaderFile(filePath);
// OpenGL needs the file contents in this format
const char * shaderDataPtr = shaderData.c_str();
glShaderSource(shaderID, 1, &shaderDataPtr, nullptr);
// Moment of truth
glCompileShader(shaderID);
// Error checking
GLint isCompiled = 0;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &isCompiled);
if (!isCompiled)
{
// Get size of error log
GLint maxLogLength;
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &maxLogLength);
// Read error log
std::vector<GLchar> compileErrorLog(maxLogLength);
glGetShaderInfoLog(shaderID, maxLogLength, &maxLogLength, &compileErrorLog[0]);
// Avoid leaking the shader
glDeleteShader(shaderID);
// Fail
perror(&compileErrorLog[0]);
fatalError("Could not compile shader " + filePath + ".");
}
}
void GLSLProgram::linkShaders()
{
// Program object represents fully executable code
_shaderProgramID = glCreateProgram();
// Attach shaders
glAttachShader(_shaderProgramID, _vertShaderID);
glAttachShader(_shaderProgramID, _fragShaderID);
// Moment of truth
glLinkProgram(_shaderProgramID);
// Error handling
GLint isLinked = 0;
glGetProgramiv(_shaderProgramID, GL_LINK_STATUS, &isLinked);
if (!isLinked)
{
// Get size of error log
GLint maxLogLength;
glGetProgramiv(_shaderProgramID, GL_INFO_LOG_LENGTH, &maxLogLength);
// Read error log
std::vector<GLchar> linkErrorLog(maxLogLength);
glGetProgramInfoLog(_shaderProgramID, maxLogLength, &maxLogLength, &linkErrorLog[0]);
// Avoid leaking the program and shaders
glDeleteProgram(_shaderProgramID);
glDeleteShader(_vertShaderID);
glDeleteShader(_fragShaderID);
// Fail
perror(&linkErrorLog[0]);
fatalError("Could not link shaders.");
}
// Clean up leaks after successful link
glDetachShader(_shaderProgramID, _vertShaderID);
glDetachShader(_shaderProgramID, _fragShaderID);
glDeleteShader(_vertShaderID);
glDeleteShader(_fragShaderID);
}
void GLSLProgram::use()
{
glUseProgram(_shaderProgramID);
}
void GLSLProgram::unuse()
{
glUseProgram(0);
}
GLint GLSLProgram::getUniformLocation(const std::string& uniformName)
{
GLint location = glGetUniformLocation(_shaderProgramID, uniformName.c_str());
if (location == GL_INVALID_INDEX)
{
return 0;
}
return location;
}