ShaderProgram.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include "ShaderProgram.h"
  2. #include <fstream>
  3. #include <cstring>
  4. ShaderProgram::ShaderProgram()
  5. {
  6. }
  7. ShaderProgram::~ShaderProgram()
  8. {
  9. if(vertexShader != 0)
  10. {
  11. glDeleteShader(vertexShader);
  12. }
  13. if(fragmentShader != 0)
  14. {
  15. glDeleteShader(fragmentShader);
  16. }
  17. if(program != 0)
  18. {
  19. glDeleteProgram(program);
  20. }
  21. }
  22. bool ShaderProgram::isValid()
  23. {
  24. return valid;
  25. }
  26. GLuint ShaderProgram::getProgram()
  27. {
  28. return program;
  29. }
  30. void ShaderProgram::compile(const GLchar* vertexPath, const GLchar* fragmentPath)
  31. {
  32. if(valid)
  33. {
  34. return;
  35. }
  36. GLchar* vertexData = readFile(vertexPath);
  37. if(vertexData == nullptr)
  38. {
  39. cout << "cannot read " << vertexPath << endl;
  40. return;
  41. }
  42. GLchar* fragmentData = readFile(fragmentPath);
  43. if(fragmentData == nullptr)
  44. {
  45. cout << "cannot read " << fragmentPath << endl;
  46. delete[] vertexData;
  47. return;
  48. }
  49. compile(vertexPath, vertexData, fragmentPath, fragmentData);
  50. delete[] vertexData;
  51. delete[] fragmentData;
  52. }
  53. GLchar* ShaderProgram::readFile(const GLchar* name)
  54. {
  55. ifstream in;
  56. in.open(name);
  57. if(!in.fail())
  58. {
  59. int size = 128;
  60. int index = 0;
  61. GLchar* content = new GLchar[size];
  62. while(true)
  63. {
  64. GLchar c = in.get();
  65. if(in.eof())
  66. {
  67. break;
  68. }
  69. if(index >= size - 1)
  70. {
  71. GLchar* newContent = new GLchar[size * 2];
  72. memcpy(newContent, content, size);
  73. size *= 2;
  74. delete[] content;
  75. content = newContent;
  76. }
  77. content[index] = c;
  78. index++;
  79. }
  80. content[index] = '\0';
  81. index++;
  82. in.close();
  83. return content;
  84. }
  85. return nullptr;
  86. }
  87. bool ShaderProgram::checkShaderErrors(const GLchar* name, GLuint shader)
  88. {
  89. bool returnValue = false;
  90. cout << "compiling " << name << " shader ..." << endl;
  91. GLenum error = glGetError();
  92. if(error)
  93. {
  94. cout << "error: " << glGetError() << endl;
  95. returnValue = true;
  96. }
  97. else
  98. {
  99. cout << "no error occured ..." << endl;
  100. }
  101. GLint compiled[1];
  102. glGetShaderiv(shader, GL_COMPILE_STATUS, compiled);
  103. if(compiled[0])
  104. {
  105. cout << name << " shader successfully compiled" << endl;
  106. }
  107. else
  108. {
  109. cout << name << "compiling of " << name << " failed:" << endl;
  110. GLchar buffer[512];
  111. GLsizei bufferSize = 512;
  112. GLsizei charsUsed = 0;
  113. glGetShaderInfoLog(shader, bufferSize, &charsUsed, buffer);
  114. // glGetProgramInfoLog should be null terminated ...
  115. buffer[bufferSize - 1] = '\0';
  116. cout << buffer << endl;
  117. returnValue = true;
  118. }
  119. return returnValue;
  120. }
  121. void ShaderProgram::compile(const GLchar* vertexPath, const GLchar* vertexData, const GLchar* fragmentPath, const GLchar* fragmentData)
  122. {
  123. vertexShader = glCreateShader(GL_VERTEX_SHADER);
  124. glShaderSource(vertexShader, 1, &vertexData, nullptr);
  125. glCompileShader(vertexShader);
  126. if(checkShaderErrors(vertexPath, vertexShader))
  127. {
  128. return;
  129. }
  130. fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  131. glShaderSource(fragmentShader, 1, &fragmentData, nullptr);
  132. glCompileShader(fragmentShader);
  133. if(checkShaderErrors(fragmentPath, fragmentShader))
  134. {
  135. return;
  136. }
  137. program = glCreateProgram();
  138. glAttachShader(program, vertexShader);
  139. glAttachShader(program, fragmentShader);
  140. glLinkProgram(program);
  141. cout << "linking shaders to program ..." << endl;
  142. GLenum error = glGetError();
  143. if(error)
  144. {
  145. cout << "error: " << glGetError() << endl;
  146. return;
  147. }
  148. else
  149. {
  150. cout << "no error occured ..." << endl;
  151. }
  152. GLint compiled[1];
  153. glGetProgramiv(program, GL_LINK_STATUS, compiled);
  154. if(compiled[0])
  155. {
  156. cout << "shaders successfully linked" << endl;
  157. }
  158. else
  159. {
  160. cout << "linking of shaders failed:" << endl;
  161. GLchar buffer[512];
  162. GLsizei bufferSize = 512;
  163. GLsizei charsUsed = 0;
  164. glGetProgramInfoLog(program, bufferSize, &charsUsed, buffer);
  165. // glGetProgramInfoLog should be null terminated ...
  166. buffer[bufferSize - 1] = '\0';
  167. cout << buffer << endl;
  168. return;
  169. }
  170. valid = true;
  171. }