/src/util/shader.cpp

https://gitlab.com/geoff-nagy/cube-instanced-rendering · C++ · 239 lines · 194 code · 45 blank · 0 comment · 13 complexity · 563daceb49a87b5291aec9b3b1b4d51f MD5 · raw file

  1. #include "util/shader.h"
  2. #include "gl/glew.h"
  3. #include "glm/glm.hpp"
  4. using namespace glm;
  5. #include <fstream>
  6. #include <cstdlib>
  7. #include <iostream>
  8. #include <string>
  9. using namespace std;
  10. Shader::Shader(string vertex, string frag)
  11. {
  12. GLint vertexCompiled;
  13. GLint fragCompiled;
  14. char *vertexFile = textFileRead(vertex.c_str());
  15. char *fragFile = textFileRead(frag.c_str());
  16. const char *vv = vertexFile;
  17. const char *ff = fragFile;
  18. vertexShader = glCreateShader(GL_VERTEX_SHADER);
  19. fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  20. glShaderSource(vertexShader, 1, &vv, NULL);
  21. glShaderSource(fragmentShader, 1, &ff, NULL);
  22. glCompileShader(vertexShader);
  23. glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexCompiled);
  24. if(!vertexCompiled)
  25. {
  26. cout << "Shader::Shader() could not compile vertex shader " << vertex << endl;
  27. printShaderLogInfo(vertexShader);
  28. exit(1);
  29. }
  30. glCompileShader(fragmentShader);
  31. glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragCompiled);
  32. if(!fragCompiled)
  33. {
  34. cout << "Shader::Shader() could not compile fragment shader " << frag << endl;
  35. printShaderLogInfo(fragmentShader);
  36. exit(1);
  37. }
  38. if(vertexCompiled && fragCompiled)
  39. {
  40. program = glCreateProgram();
  41. glAttachShader(program, vertexShader);
  42. glAttachShader(program, fragmentShader);
  43. }
  44. }
  45. Shader::~Shader()
  46. {
  47. glDetachShader(program, vertexShader);
  48. glDetachShader(program, fragmentShader);
  49. glDeleteShader(vertexShader);
  50. glDeleteShader(fragmentShader);
  51. glDeleteProgram(program);
  52. }
  53. void Shader::link()
  54. {
  55. GLint linked = false;
  56. glLinkProgram(program);
  57. glGetProgramiv(program, GL_LINK_STATUS, &linked);
  58. if(!linked)
  59. {
  60. cerr << "Shader::Shader() compiled but could not be linked" << endl;
  61. printShaderLogInfo(vertexShader);
  62. printShaderLogInfo(fragmentShader);
  63. exit(1);
  64. }
  65. }
  66. void Shader::bind()
  67. {
  68. glUseProgram(program);
  69. }
  70. void Shader::unbind()
  71. {
  72. glUseProgram(0);
  73. }
  74. void Shader::bindAttrib(const char *var, unsigned int index)
  75. {
  76. glBindAttribLocation(program, index, var);
  77. }
  78. void Shader::uniform1f(const char *var, float val)
  79. {
  80. glUniform1f(getUniLoc(program, var), val);
  81. }
  82. void Shader::uniform1i(const char *var, int val)
  83. {
  84. glUniform1i(getUniLoc(program, var), val);
  85. }
  86. void Shader::uniform1fv(const char *var, int count, float *vals)
  87. {
  88. glUniform1fv(getUniLoc(program, var), count, vals);
  89. }
  90. void Shader::uniform2f(const char *var, float v1, float v2)
  91. {
  92. glUniform2f(getUniLoc(program, var), v1, v2);
  93. }
  94. void Shader::uniform2fv(const char *var, int count, float *vals)
  95. {
  96. glUniform2fv(getUniLoc(program, var), count, vals);
  97. }
  98. void Shader::uniformVec2(const char *var, vec2 v)
  99. {
  100. uniform2f(var, v.x, v.y);
  101. }
  102. void Shader::uniform3iv(const char *var, int count, int *vals)
  103. {
  104. glUniform3iv(getUniLoc(program, var), count, vals);
  105. }
  106. void Shader::uniform3fv(const char *var, int count, float *vals)
  107. {
  108. glUniform3fv(getUniLoc(program, var), count, vals);
  109. }
  110. void Shader::uniform3f(const char *var, const float v1, const float v2, const float v3)
  111. {
  112. glUniform3f(getUniLoc(program, var), v1, v2, v3);
  113. }
  114. void Shader::uniformVec3(const char *var, vec3 v)
  115. {
  116. uniform3f(var, v.x, v.y, v.z);
  117. }
  118. void Shader::uniformMatrix3fv(const char *var, GLsizei count, GLfloat *vals, bool transpose)
  119. {
  120. glUniformMatrix3fv(getUniLoc(program, var), count, transpose, vals);
  121. }
  122. void Shader::uniform4iv(const char *var, int count, int *vals)
  123. {
  124. glUniform4iv(getUniLoc(program, var), count, vals);
  125. }
  126. void Shader::uniform4fv(const char *var, int count, float *vals)
  127. {
  128. glUniform4fv(getUniLoc(program, var), count, vals);
  129. }
  130. void Shader::uniform4f(const char *var, float v1, float v2, float v3, float v4)
  131. {
  132. glUniform4f(getUniLoc(program, var), v1, v2, v3, v4);
  133. }
  134. void Shader::uniformVec4(const char *var, vec4 v)
  135. {
  136. uniform4f(var, v.x, v.y, v.z, v.w);
  137. }
  138. void Shader::uniformMatrix4fv(const char *var, GLsizei count, GLfloat *vals, bool transpose)
  139. {
  140. glUniformMatrix4fv(getUniLoc(program, var), count, transpose, vals);
  141. }
  142. GLint Shader::getUniLoc(GLuint program, const char *name)
  143. {
  144. GLint loc;
  145. loc = glGetUniformLocation(program, name);
  146. if(loc == -1)
  147. {
  148. cerr << "Shader::getUniLoc(): uniform '" << name << "' has not been defined" << endl;
  149. }
  150. return loc;
  151. }
  152. void Shader::printShaderLogInfo(GLuint obj)
  153. {
  154. int infologLength = 0;
  155. int charsWritten = 0;
  156. char *infoLog;
  157. glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
  158. if (infologLength > 1)
  159. {
  160. infoLog = (char *)malloc(infologLength);
  161. glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
  162. cout << infoLog << endl;
  163. free(infoLog);
  164. }
  165. }
  166. char *Shader::textFileRead(const char *fn)
  167. {
  168. FILE *fp;
  169. char *content = NULL;
  170. int count=0;
  171. if (fn != NULL)
  172. {
  173. fp = fopen(fn,"rt");
  174. if (fp != NULL)
  175. {
  176. fseek(fp, 0, SEEK_END);
  177. count = ftell(fp);
  178. rewind(fp);
  179. if (count > 0)
  180. {
  181. content = (char*)malloc(sizeof(char) * (count+1));
  182. count = fread(content, sizeof(char), count, fp);
  183. content[count] = '\0';
  184. }
  185. fclose(fp);
  186. }
  187. else
  188. {
  189. cerr << "Shader::textFileRead() failed to open '" << fn << "'" << endl;
  190. exit(1);
  191. }
  192. }
  193. return content;
  194. }