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.

111 lines
3.8 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. #include "shader.h"
  2. #include "utils.h"
  3. #include "vertexbuffer.h"
  4. void Shader::Init(const char * vs, const char * fs)
  5. {
  6. int nFileSize = 0;
  7. const char*vsCode = (char*)LoadFileContent(vs, nFileSize);
  8. const char*fsCode = (char*)LoadFileContent(fs, nFileSize);
  9. GLuint vsShader = CompileShader(GL_VERTEX_SHADER, vsCode);
  10. if (vsShader == 0) {
  11. return;
  12. }
  13. GLuint fsShader = CompileShader(GL_FRAGMENT_SHADER, fsCode);
  14. if (fsShader == 0) {
  15. return;
  16. }
  17. mProgram = CreateProgram(vsShader, fsShader);
  18. glDeleteShader(vsShader);
  19. glDeleteShader(fsShader);
  20. if (mProgram != 0) {
  21. mModelMatrixLocation = glGetUniformLocation(mProgram, "ModelMatrix");
  22. mViewMatrixLocation = glGetUniformLocation(mProgram, "ViewMatrix");
  23. mProjectionMatrixLocation = glGetUniformLocation(mProgram, "ProjectionMatrix");
  24. mPositionLocation = glGetAttribLocation(mProgram, "position");
  25. mColorLocation = glGetAttribLocation(mProgram, "color");
  26. mTexcoordLocation = glGetAttribLocation(mProgram, "texcoord");
  27. mNormalLocation = glGetAttribLocation(mProgram, "normal");
  28. }
  29. }
  30. void Shader::Bind(float *M, float *V, float*P) {
  31. glUseProgram(mProgram);
  32. glUniformMatrix4fv(mModelMatrixLocation, 1, GL_FALSE, M);
  33. glUniformMatrix4fv(mViewMatrixLocation, 1, GL_FALSE, V);
  34. glUniformMatrix4fv(mProjectionMatrixLocation, 1, GL_FALSE, P);
  35. int iIndex = 0;
  36. for (auto iter = mUniformTextures.begin(); iter != mUniformTextures.end(); ++iter) {
  37. glActiveTexture(GL_TEXTURE0 + iIndex);
  38. glBindTexture(GL_TEXTURE_2D, iter->second->mTexture);
  39. glUniform1i(iter->second->mLocation, iIndex++);
  40. }
  41. for (auto iter = mUniformVec4s.begin(); iter != mUniformVec4s.end(); ++iter) {
  42. glUniform4fv(iter->second->mLocation, 1, iter->second->v);
  43. }
  44. glEnableVertexAttribArray(mPositionLocation);
  45. glVertexAttribPointer(mPositionLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
  46. glEnableVertexAttribArray(mColorLocation);
  47. glVertexAttribPointer(mColorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 4));
  48. glEnableVertexAttribArray(mTexcoordLocation);
  49. glVertexAttribPointer(mTexcoordLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 8));
  50. glEnableVertexAttribArray(mNormalLocation);
  51. glVertexAttribPointer(mNormalLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 12));
  52. }
  53. void Shader::SetTexture(const char * name, const char*imagePath) {
  54. auto iter = mUniformTextures.find(name);
  55. if (iter == mUniformTextures.end()) {
  56. GLint location = glGetUniformLocation(mProgram, name);
  57. if (location != -1) {
  58. UniformTexture* t = new UniformTexture;
  59. t->mLocation = location;
  60. t->mTexture = CreateTexture2DFromBMP(imagePath);
  61. mUniformTextures.insert(std::pair<std::string, UniformTexture*>(name, t));
  62. }
  63. }
  64. else {
  65. glDeleteTextures(1, &iter->second->mTexture);
  66. iter->second->mTexture = CreateTexture2DFromBMP(imagePath);
  67. }
  68. }
  69. void Shader::SetVec4(const char * name, float x, float y, float z, float w) {
  70. auto iter = mUniformVec4s.find(name);
  71. if (iter == mUniformVec4s.end()) {
  72. GLint location = glGetUniformLocation(mProgram, name);
  73. if (location != -1) {
  74. UniformVector4f*v = new UniformVector4f;
  75. v->v[0] = x;
  76. v->v[1] = y;
  77. v->v[2] = z;
  78. v->v[3] = w;
  79. v->mLocation = location;
  80. mUniformVec4s.insert(std::pair<std::string, UniformVector4f*>(name, v));
  81. }
  82. }
  83. else {
  84. iter->second->v[0] = x;
  85. iter->second->v[1] = y;
  86. iter->second->v[2] = z;
  87. iter->second->v[3] = w;
  88. }
  89. }
  90. void Shader::SetTexture(const char * name, GLuint texture) {
  91. auto iter = mUniformTextures.find(name);
  92. if (iter == mUniformTextures.end()) {
  93. GLint location = glGetUniformLocation(mProgram, name);
  94. if (location != -1) {
  95. UniformTexture*t = new UniformTexture;
  96. t->mLocation = location;
  97. t->mTexture = texture;
  98. mUniformTextures.insert(std::pair<std::string, UniformTexture*>(name, t));
  99. }
  100. }
  101. else {
  102. glDeleteTextures(1, &iter->second->mTexture);
  103. iter->second->mTexture = texture;
  104. }
  105. }