You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
6.1 KiB

4 years ago
4 years ago
  1. #include "shader.h"
  2. #include "utils.h"
  3. #include "vertexbuffer.h"
  4. GLuint Shader::CompileShader(GLuint shaderType, const char * shaderCode)
  5. {
  6. GLuint shader = glCreateShader(shaderType);
  7. glShaderSource(shader, 1, &shaderCode, nullptr);
  8. glCompileShader(shader);
  9. GLint compileResult = GL_TRUE;
  10. glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
  11. if (compileResult == GL_FALSE) {
  12. char szLog[1024] = { 0 };
  13. GLsizei logLen = 0;
  14. glGetShaderInfoLog(shader, 1024, &logLen, szLog);
  15. printf("Compile Shader fail error log : %s \nshader code :\n%s\n", szLog, shaderCode);
  16. glDeleteShader(shader);
  17. shader = 0;
  18. }
  19. return shader;
  20. }
  21. GLuint Shader::CreateProgram(GLuint vsShader, GLuint fsShader)
  22. {
  23. GLuint program = glCreateProgram();
  24. glAttachShader(program, vsShader);
  25. glAttachShader(program, fsShader);
  26. glLinkProgram(program);
  27. glDetachShader(program, vsShader);
  28. glDetachShader(program, fsShader);
  29. GLint nResult;
  30. glGetProgramiv(program, GL_LINK_STATUS, &nResult);
  31. if (nResult == GL_FALSE) {
  32. char log[1024] = { 0 };
  33. GLsizei writed = 0;
  34. glGetProgramInfoLog(program, 1024, &writed, log);
  35. printf("create gpu program fail,link error : %s\n", log);
  36. glDeleteProgram(program);
  37. program = 0;
  38. }
  39. return program;
  40. }
  41. void Shader::Init(const char * vs, const char * fs)
  42. {
  43. int nFileSize = 0;
  44. const char* vsCode = (char*)LoadFileContent(vs, nFileSize);
  45. const char* fsCode = (char*)LoadFileContent(fs, nFileSize);
  46. GLuint vsShader = CompileShader(GL_VERTEX_SHADER, vsCode);
  47. if (vsShader == 0) {
  48. return;
  49. }
  50. GLuint fsShader = CompileShader(GL_FRAGMENT_SHADER, fsCode);
  51. if (fsShader == 0) {
  52. return;
  53. }
  54. mProgram = CreateProgram(vsShader, fsShader);
  55. glDeleteShader(vsShader);
  56. glDeleteShader(fsShader);
  57. if (mProgram != 0) {
  58. mModelMatrixLocation = glGetUniformLocation(mProgram, "ModelMatrix");
  59. mViewMatrixLocation = glGetUniformLocation(mProgram, "ViewMatrix");
  60. mProjectionMatrixLocation = glGetUniformLocation(mProgram, "ProjectionMatrix");
  61. mPositionLocation = glGetAttribLocation(mProgram, "position");
  62. mColorLocation = glGetAttribLocation(mProgram, "color");
  63. mTexcoordLocation = glGetAttribLocation(mProgram, "texcoord");
  64. mNormalLocation = glGetAttribLocation(mProgram, "normal");
  65. }
  66. }
  67. void Shader::Bind(float *M, float *V, float*P)
  68. {
  69. glUseProgram(mProgram);
  70. if (mModelMatrixLocation >= 0) glUniformMatrix4fv(mModelMatrixLocation, 1, GL_FALSE, M);
  71. if (mViewMatrixLocation >= 0)glUniformMatrix4fv(mViewMatrixLocation, 1, GL_FALSE, V);
  72. if (mProjectionMatrixLocation >= 0)glUniformMatrix4fv(mProjectionMatrixLocation, 1, GL_FALSE, P);
  73. int iIndex = 0;
  74. for (auto iter = mUniformTextures.begin(); iter != mUniformTextures.end(); ++iter) {
  75. glActiveTexture(GL_TEXTURE0 + iIndex);
  76. glBindTexture(GL_TEXTURE_2D, iter->second->mTexture);
  77. glUniform1i(iter->second->mLocation, iIndex++);
  78. }
  79. for (auto iter = mUniformTextureCubes.begin(); iter != mUniformTextureCubes.end(); ++iter) {
  80. glActiveTexture(GL_TEXTURE0 + iIndex);
  81. glBindTexture(GL_TEXTURE_CUBE_MAP, iter->second->mTexture);
  82. glUniform1i(iter->second->mLocation, iIndex++);
  83. }
  84. for (auto iter = mUniformVec4s.begin(); iter != mUniformVec4s.end(); ++iter) {
  85. glUniform4fv(iter->second->mLocation, 1, iter->second->v);
  86. }
  87. if (mPositionLocation >= 0) {
  88. glEnableVertexAttribArray(mPositionLocation);
  89. glVertexAttribPointer(mPositionLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 0));
  90. }
  91. if (mColorLocation >= 0) {
  92. glEnableVertexAttribArray(mColorLocation);
  93. glVertexAttribPointer(mColorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 4));
  94. }
  95. if (mTexcoordLocation >= 0) {
  96. glEnableVertexAttribArray(mTexcoordLocation);
  97. glVertexAttribPointer(mTexcoordLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 8));
  98. }
  99. if (mNormalLocation >= 0) {
  100. glEnableVertexAttribArray(mNormalLocation);
  101. glVertexAttribPointer(mNormalLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 12));
  102. }
  103. }
  104. void Shader::SetTexture(const char * name, const char * imagePath)
  105. {
  106. auto iter = mUniformTextures.find(name);
  107. if (iter == mUniformTextures.end()) {
  108. GLint location = glGetUniformLocation(mProgram, name);
  109. if (location != -1) {
  110. UniformTexture* t = new UniformTexture;
  111. t->mLocation = location;
  112. t->mTexture = CreateTextureFromFile(imagePath);
  113. mUniformTextures.insert(std::pair<std::string, UniformTexture*>(name, t));
  114. }
  115. else {
  116. glDeleteTextures(1, &iter->second->mTexture);
  117. iter->second->mTexture = CreateTextureFromFile(imagePath);
  118. }
  119. }
  120. }
  121. void Shader::SetVec4(const char * name, float x, float y, float z, float w)
  122. {
  123. auto iter = mUniformVec4s.find(name);
  124. if (iter == mUniformVec4s.end()) {
  125. GLuint location = glGetUniformLocation(mProgram, name);
  126. if (location != -1) {
  127. UniformVector4f* v = new UniformVector4f;
  128. v->v[0] = x;
  129. v->v[1] = y;
  130. v->v[2] = z;
  131. v->v[3] = w;
  132. v->mLocation = location;
  133. mUniformVec4s.insert(std::pair<std::string, UniformVector4f*>(name, v));
  134. }
  135. }
  136. else {
  137. iter->second->v[0] = x;
  138. iter->second->v[1] = x;
  139. iter->second->v[2] = x;
  140. iter->second->v[3] = x;
  141. }
  142. }
  143. GLuint Shader::SetTexture(const char * name, GLuint texture) {
  144. auto iter = mUniformTextures.find(name);
  145. GLuint oldTexture = 0;
  146. if (iter == mUniformTextures.end()) {
  147. GLint location = glGetUniformLocation(mProgram, name);
  148. if (location != -1) {
  149. UniformTexture*t = new UniformTexture;
  150. t->mLocation = location;
  151. t->mTexture = texture;
  152. mUniformTextures.insert(std::pair<std::string, UniformTexture*>(name, t));
  153. }
  154. }
  155. else {
  156. oldTexture = iter->second->mTexture;
  157. iter->second->mTexture = texture;
  158. }
  159. return oldTexture;
  160. }
  161. GLuint Shader::SetTextureCube(const char * name, GLuint texture) {
  162. auto iter = mUniformTextureCubes.find(name);
  163. GLuint oldTexture = 0;
  164. if (iter == mUniformTextureCubes.end()) {
  165. GLint location = glGetUniformLocation(mProgram, name);
  166. if (location != -1) {
  167. UniformTextureCube*t = new UniformTextureCube;
  168. t->mLocation = location;
  169. t->mTexture = texture;
  170. mUniformTextureCubes.insert(std::pair<std::string, UniformTextureCube*>(name, t));
  171. }
  172. }
  173. else {
  174. oldTexture = iter->second->mTexture;
  175. iter->second->mTexture = texture;
  176. }
  177. return oldTexture;
  178. }