-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathGLSLProgram.cpp
126 lines (115 loc) · 3.78 KB
/
GLSLProgram.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
#include "GLSLProgram.h"
#include "Errors.h"
#include <fstream>
#include <vector>
namespace NeroEngine{
GLSLProgram::GLSLProgram() :
_numAttributes(0),
_programID(0),
_vertexShaderID(0),
_fragmentShaderID(0){
}
GLSLProgram::~GLSLProgram()
{
}
void GLSLProgram::complieShaders(const std::string& vertexShaderFilePath, const std::string& fragmentShaderFilePath){
_programID = glCreateProgram();
_vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
if (_vertexShaderID == 0){
fatalError("VertexShader fail to create!");
}
_fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
if (_fragmentShaderID == 0){
fatalError("FragmentShader fail to create!");
}
complieShader(vertexShaderFilePath, _vertexShaderID);
complieShader(fragmentShaderFilePath, _fragmentShaderID);
}
void GLSLProgram::linkShaders(){
if (_programID == 0){
fatalError("Program failed to create!");
}
glAttachShader(_programID, _vertexShaderID);
glAttachShader(_programID, _fragmentShaderID);
//Link our program
glLinkProgram(_programID);
//Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(_programID, GL_LINK_STATUS, (int *)&isLinked);
if (isLinked == GL_FALSE)
{
GLint maxLength = 0;
glGetProgramiv(_programID, GL_INFO_LOG_LENGTH, &maxLength);
//The maxLength includes the NULL character
std::vector<char> infoLog(maxLength);
glGetProgramInfoLog(_programID, maxLength, &maxLength, &infoLog[0]);
//We don't need the program anymore.
glDeleteProgram(_programID);
//Don't leak shaders either.
glDeleteShader(_vertexShaderID);
glDeleteShader(_fragmentShaderID);
//Use the infoLog as you see fit.
//In this simple program, we'll just leave
printf("%s\n", &(infoLog[0]));
fatalError("Link shader failed!");
}
//Always detach shaders after a successful link.
glDetachShader(_programID, _vertexShaderID);
glDetachShader(_programID, _fragmentShaderID);
glDeleteShader(_vertexShaderID);
glDeleteShader(_fragmentShaderID);
}
void GLSLProgram::complieShader(const std::string& filePath, GLuint& id){
std::fstream vertexFile(filePath);
if (vertexFile.fail()){
perror(filePath.c_str());
fatalError("Failed to open" + filePath);
}
std::string fileContents = "";
std::string line;
while (std::getline(vertexFile, line)){
fileContents += line + "\n";
}
vertexFile.close();
const char* contentsPtr = fileContents.c_str();
glShaderSource(id, 1, &contentsPtr, nullptr);//load GLSL string
glCompileShader(id);//compile GLSL
GLint success = 0;
glGetShaderiv(id, GL_COMPILE_STATUS, &success);
if (success == 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.
printf("%s\n", &(errorLog[0]));
fatalError("Shader" + filePath + " failed to complie!");
}
}
void GLSLProgram::addAttribute(const std::string& attributeName){
glBindAttribLocation(_programID, _numAttributes++, attributeName.c_str());
}
GLint GLSLProgram::getUniformLocation(const std::string& uniformLocationName){
GLint location = glGetUniformLocation(_programID, uniformLocationName.c_str());
if (location == GL_INVALID_INDEX){
fatalError("uniform" + uniformLocationName + "not found!");
}
return location;
}
void GLSLProgram::use(){
glUseProgram(_programID);
for (int i = 0; i < _numAttributes; i++){
glEnableVertexAttribArray(i);
}
}
void GLSLProgram::unuse(){
glUseProgram(0);
for (int i = 0; i < _numAttributes; i++){
glDisableVertexAttribArray(i);
}
}
}