Bubba-3D  0.9.0
Awesome game engine!
ShaderProgram.cpp
1 /*
2  * This file is part of Bubba-3D.
3  *
4  * Bubba-3D is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Bubba-3D is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with Bubba-3D. If not, see http://www.gnu.org/licenses/.
16  */
17 #include "ShaderProgram.h"
18 #include "Logger.h"
19 #include "VertexShader.h"
20 
21 #define MAX_LOG_SIZE 1024
22 
23 ShaderProgram::ShaderProgram() {
24 
25 }
26 
27 void ShaderProgram::loadShader(IShader *vertexShader, IShader *fragmentShader) {
28  this->vertexShader = vertexShader;
29  this->fragmentShader = fragmentShader;
30  createProgram(vertexShader->getGLId(), fragmentShader->getGLId());
31  linkProgram();
32 }
33 
34 void ShaderProgram::createProgram(GLuint vertexShader, GLuint fragmentShader) {
35  this->shaderID = glCreateProgram();
36  glAttachShader(this->shaderID, vertexShader);
37  glAttachShader(this->shaderID, fragmentShader);
38 
39 }
40 
41 void ShaderProgram::linkProgram() {
42  glLinkProgram(this->shaderID);
43  checkLinkageErrors();
44 }
45 
46 void ShaderProgram::checkLinkageErrors() {
47  GLint successfullyLinked;
48  glGetProgramiv(this->shaderID, GL_LINK_STATUS, &successfullyLinked);
49  if(!successfullyLinked) {
50  logLinkageError();
51  }
52 }
53 
54 void ShaderProgram::logLinkageError() {
55  GLchar linkageLog[MAX_LOG_SIZE];
56 
57  glGetShaderInfoLog(this->shaderID, MAX_LOG_SIZE, NULL, linkageLog);
58  Logger::logError("Failed to compile shader of type PROGRAM\n"
59  + std::to_string(*linkageLog));
60 }
61 
63  glUseProgram(this->shaderID);
64 }
65 
67  glGetIntegerv(GL_CURRENT_PROGRAM, &previousShaderProgram);
68 }
69 
71  glUseProgram(previousShaderProgram);
72 }
73 
74 GLint ShaderProgram::getUniformLocation(const std::string name) {
75  std::map<std::string, GLint>::iterator it = uniformLocations.find(name);
76  if(it != uniformLocations.end()) {
77  return it->second;
78  } else {
79  GLint location = glGetUniformLocation(shaderID, name.c_str());
80  uniformLocations.insert(std::pair<std::string,GLint>(name, location));
81  return location;
82  }
83 }
84 
85 void ShaderProgram::setUniform1i(std::string name, int value) {
86  glUniform1i(getUniformLocation(name), value);
87 }
88 
89 void ShaderProgram::setUniform1f(std::string name, float value) {
90  glUniform1f(getUniformLocation(name), value);
91 }
92 
93 void ShaderProgram::setUniform3f(std::string name, chag::float3 value){
94  glUniform3fv(getUniformLocation(name),1, &value.x);
95 }
96 
97 void ShaderProgram::setUniform4f(std::string name, chag::float4 value) {
98  glUniform4fv(getUniformLocation(name),1,&value.x);
99 }
100 
101 void ShaderProgram::setUniformMatrix4fv(std::string name, chag::float4x4 matrix) {
102  glUniformMatrix4fv(getUniformLocation(name), 1, false, &matrix.c1.x);
103 }
104 
105 void ShaderProgram::setUniform2f(std::string name, chag::float2 value) {
106  glUniform2fv(getUniformLocation(name),1,&value.x);
107 }
108 
109 void ShaderProgram::setUniformBufferObjectBinding(std::string bufferName, int index) {
110  GLuint matricesUniform = glGetUniformBlockIndex(shaderID, bufferName.c_str());
111  glUniformBlockBinding(shaderID, matricesUniform, index);
112 }
113 
114 void ShaderProgram::initUniformBufferObject(std::string bufferName, int size, int index) {
115  GLuint uniformBufferObject;
116  glGenBuffers(1, &uniformBufferObject);
117  glBindBuffer(GL_UNIFORM_BUFFER, uniformBufferObject);
118  glBufferData(GL_UNIFORM_BUFFER, size, NULL, GL_STATIC_DRAW);
119  glBindBuffer(GL_UNIFORM_BUFFER, 0);
120 
121  glBindBufferRange(GL_UNIFORM_BUFFER, index, uniformBufferObject, 0, size);
122  glBindBuffer(GL_UNIFORM_BUFFER, 0);
123 
124  uniformLocations.insert(std::pair<std::string, GLint>(bufferName, uniformBufferObject));
125 }
126 
127 void ShaderProgram::setUniformBufferSubData(std::string bufferName, int offset, int size, const GLvoid *data) {
128  glBindBuffer(GL_UNIFORM_BUFFER, getUniformLocation(bufferName));
129  glFinish();
130  glBufferSubData(GL_UNIFORM_BUFFER, offset, size, data);
131  glBindBuffer(GL_UNIFORM_BUFFER, 0);
132 }
133 
134 const char *textFileRead(const char *fn, bool fatalError) {
135 
136  FILE *fp;
137  char *content = NULL;
138  int count = 0;
139 
140  if (fn != NULL) {
141  fp = fopen(fn, "rt");
142  if (fp != NULL) {
143  fseek(fp, 0, SEEK_END);
144  count = ftell(fp);
145  fseek(fp, 0, SEEK_SET);
146 
147  if (count > 0) {
148  content = new char[count+1];
149  count = fread( content, sizeof(char), count, fp);
150  content[count] = '\0';
151  } else {
152  if (fatalError) {
153  char buffer[256];
154  sprintf(buffer, "File '%s' is empty\n", fn);
155  fatal_error(buffer);
156  }
157  }
158 
159  fclose(fp);
160  } else {
161  if (fatalError) {
162  char buffer[256];
163  sprintf(buffer, "Unable to read file '%s'\n", fn);
164  fatal_error(buffer);
165  }
166  }
167  } else {
168  if (fatalError)
169  fatal_error("textFileRead - argument NULL\n");
170  }
171 
172  return content;
173 }
174 
175 
176 
177 
178 
179 
180 
181 
182 
183 
184 
185 
186 
187 
188 
189 
190 
191 
192 
void restorePreviousShaderProgram()
void loadShader(IShader *vertexShader, IShader *fragmentShader)
void backupCurrentShaderProgram()