ShaderProgram.cpp 4.5 KB

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