WorldShader.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #include "client/engine/shader/WorldShader.h"
  2. #include "client/engine/Wrapper.h"
  3. WorldShader::WorldShader()
  4. {
  5. }
  6. WorldShader::~WorldShader()
  7. {
  8. glDeleteFramebuffers(1, &framebuffer);
  9. glDeleteTextures(1, &positionTexture);
  10. glDeleteTextures(1, &normalTexture);
  11. glDeleteTextures(1, &colorTexture);
  12. glDeleteTextures(1, &depthTexture);
  13. }
  14. bool WorldShader::init()
  15. {
  16. program.compile("resources/shader/worldVertex.vs", "resources/shader/worldFragment.fs");
  17. if(!program.isValid())
  18. {
  19. return false;
  20. }
  21. // generate framebuffer
  22. glGenFramebuffers(1, &framebuffer);
  23. glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
  24. // position texture
  25. glGenTextures(1, &positionTexture);
  26. glBindTexture(GL_TEXTURE_2D, positionTexture);
  27. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, Engine::getWidth(), Engine::getHeight(), 0, GL_RGB, GL_FLOAT, NULL);
  28. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  29. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  30. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  31. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  32. // attache position texture to framebuffer
  33. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, positionTexture, 0);
  34. // normal texture
  35. glGenTextures(1, &normalTexture);
  36. glBindTexture(GL_TEXTURE_2D, normalTexture);
  37. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, Engine::getWidth(), Engine::getHeight(), 0, GL_RGB, GL_FLOAT, NULL);
  38. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  39. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  40. // attache normal texture to framebuffer
  41. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normalTexture, 0);
  42. // color texture
  43. glGenTextures(1, &colorTexture);
  44. glBindTexture(GL_TEXTURE_2D, colorTexture);
  45. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Engine::getWidth(), Engine::getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  46. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  47. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  48. // attache color texture to framebuffer
  49. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, colorTexture, 0);
  50. // depth texture
  51. glGenTextures(1, &depthTexture);
  52. glBindTexture(GL_TEXTURE_2D, depthTexture);
  53. glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, Engine::getWidth(), Engine::getHeight(), 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
  54. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  55. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  56. // attache depth texture to framebuffer
  57. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
  58. // set color attachements for the framebuffer
  59. GLuint attachments[3] =
  60. {
  61. GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2
  62. };
  63. glDrawBuffers(3, attachments);
  64. // check if framebuffer is okay
  65. if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
  66. {
  67. cout << "world frame buffer is not complete!" << endl;
  68. return false;
  69. }
  70. // unbind framebuffer
  71. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  72. // get uniform locations
  73. unifProjMatrix = glGetUniformLocation(program.getProgram(), "projMatrix");
  74. unifViewMatrix = glGetUniformLocation(program.getProgram(), "viewMatrix");
  75. unifModelMatrix = glGetUniformLocation(program.getProgram(), "modelMatrix");
  76. return true;
  77. }
  78. void WorldShader::resize()
  79. {
  80. glBindTexture(GL_TEXTURE_2D, positionTexture);
  81. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, Engine::getWidth(), Engine::getHeight(), 0, GL_RGB, GL_FLOAT, NULL);
  82. glBindTexture(GL_TEXTURE_2D, normalTexture);
  83. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, Engine::getWidth(), Engine::getHeight(), 0, GL_RGB, GL_FLOAT, NULL);
  84. glBindTexture(GL_TEXTURE_2D, colorTexture);
  85. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Engine::getWidth(), Engine::getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  86. glBindTexture(GL_TEXTURE_2D, depthTexture);
  87. glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, Engine::getWidth(), Engine::getHeight(), 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
  88. }
  89. void WorldShader::preRender(const float* projMatrix)
  90. {
  91. // bind world shader program
  92. glUseProgram(program.getProgram());
  93. // set projection matrix uniform
  94. glUniformMatrix4fv(unifProjMatrix, 1, 0, projMatrix);
  95. // all textures bind to texture unit 0
  96. glActiveTexture(GL_TEXTURE0);
  97. // bind world framebuffer
  98. glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
  99. // clear color, depth and stencil buffer
  100. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  101. // depth testing is needed
  102. glEnable(GL_DEPTH_TEST);
  103. }
  104. void WorldShader::bindPositionTexture(unsigned int textureUnit)
  105. {
  106. glActiveTexture(GL_TEXTURE0 + textureUnit);
  107. glBindTexture(GL_TEXTURE_2D, positionTexture);
  108. }
  109. void WorldShader::bindNormalTexture(unsigned int textureUnit)
  110. {
  111. glActiveTexture(GL_TEXTURE0 + textureUnit);
  112. glBindTexture(GL_TEXTURE_2D, normalTexture);
  113. }
  114. void WorldShader::bindColorTexture(unsigned int textureUnit)
  115. {
  116. glActiveTexture(GL_TEXTURE0 + textureUnit);
  117. glBindTexture(GL_TEXTURE_2D, colorTexture);
  118. }
  119. void WorldShader::bindDepthTexture(unsigned int textureUnit)
  120. {
  121. glActiveTexture(GL_TEXTURE0 + textureUnit);
  122. glBindTexture(GL_TEXTURE_2D, depthTexture);
  123. }
  124. void WorldShader::setViewMatrix(const float* data)
  125. {
  126. glUniformMatrix4fv(unifViewMatrix, 1, 0, data);
  127. }
  128. void WorldShader::setModelMatrix(const float* data)
  129. {
  130. glUniformMatrix4fv(unifModelMatrix, 1, 0, data);
  131. }