-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathGLSLProgram.cpp
More file actions
142 lines (113 loc) · 4 KB
/
GLSLProgram.cpp
File metadata and controls
142 lines (113 loc) · 4 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
#include "GLSLProgram.h"
#include "IOManager.h"
#include "Logger.h"
#include <fstream>
#include <vector>
namespace NS2
{
void GLSLProgram::compileShaders(const std::string& vertexShaderFilePath, const std::string& fragmentShaderFilePath) {
std::string vertexSource;
std::string fragSource;
IOManager::readFileToBuffer(vertexShaderFilePath, vertexSource);
IOManager::readFileToBuffer(fragmentShaderFilePath, fragSource);
compileShadersFromSource(vertexSource.c_str(), fragSource.c_str());
}
void GLSLProgram::compileShadersFromSource(const char* vertexSource, const char* fragmentSource)
{
//Vertex and fragment shaders are successfully compiled.
//Now time to link them together into a program.
//Get a program object.
m_programID = glCreateProgram();
m_vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
if (m_vertexShaderID == 0) {
logE << "Vertex shader failed to be created!" << std::endl;
}
m_fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
if (m_fragmentShaderID == 0) {
logE << "Fragment shader failed to be created!" << std::endl;
}
compileShaders(vertexSource, "Vertex shader", m_vertexShaderID);
compileShaders(fragmentSource, "Fragment shader", m_fragmentShaderID);
}
void GLSLProgram::linkShaders() {
//Attach our shaders to our program
glAttachShader(m_programID, m_vertexShaderID);
glAttachShader(m_programID, m_fragmentShaderID);
//Link our program
glLinkProgram(m_programID);
//Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(m_programID, GL_LINK_STATUS, (int *)&isLinked);
if (isLinked == GL_FALSE)
{
GLint maxLength = 0;
glGetProgramiv(m_programID, GL_INFO_LOG_LENGTH, &maxLength);
//The maxLength includes the NULL character
std::vector<GLchar> errorLog(maxLength);
glGetProgramInfoLog(m_programID, maxLength, &maxLength, &errorLog[0]);
//We don't need the program anymore.
glDeleteProgram(m_programID);
//Don't leak shaders either.
glDeleteShader(m_vertexShaderID);
glDeleteShader(m_fragmentShaderID);
logE << &(errorLog[0]) << std::endl;
logE << "Shader failed to link!" << std::endl;
Logger::exitGame();
}
//Always detach shaders after a successful link.
glDetachShader(m_programID, m_vertexShaderID);
glDetachShader(m_programID, m_fragmentShaderID);
glDeleteShader(m_vertexShaderID);
glDeleteShader(m_fragmentShaderID);
}
void GLSLProgram::addAttribute(const std::string& attributeName) {
glBindAttribLocation(m_programID, m_numAttributtes++, attributeName.c_str());
}
GLint GLSLProgram::getUniformLocation(const std::string& uniformName) {
GLint location = glGetUniformLocation(m_programID, uniformName.c_str());
if (location == GL_INVALID_INDEX) {
logE << "Uniform " << uniformName << " not found in shader!" << std::endl;
Logger::exitGame();
}
return location;
}
void GLSLProgram::use() {
glUseProgram(m_programID);
for (int i = 0; i < m_numAttributtes; i++) {
glEnableVertexAttribArray(i);
}
}
void GLSLProgram::unuse(){
glUseProgram(0);
for (int i = 0; i < m_numAttributtes; i++) {
glDisableVertexAttribArray(i);
}
}
void GLSLProgram::dispose()
{
if (m_programID)
{
glDeleteProgram(m_programID);
}
m_numAttributtes = 0;
}
void GLSLProgram::compileShaders(const char* source, const std::string& name, GLuint& id) {
glShaderSource(id, 1, &source, nullptr);
glCompileShader(id);
GLint isCompiled = 0;
glGetShaderiv(id, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE) {
GLint maxLength = 0;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(id, maxLength, &maxLength, &errorLog[0]);
// Provide the infolog in whatever manor you deem best.
// Exit with failure.
glDeleteShader(id); // Don't leak the shader.
logE << &(errorLog[0]) << std::endl;
logE << "Shader " << name << " failed to compile!" << std::endl;
Logger::exitGame();
}
}
}