Framebuffer.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #include <iostream>
  2. #include "Framebuffer.h"
  3. #include "client/Utils.h"
  4. Framebuffer::Framebuffer(u32 width, u32 height, u32 mode, int textureCompareFunc) : mode(mode), buffer(0), valid(false) {
  5. glGenFramebuffers(1, &buffer);
  6. glBindFramebuffer(GL_FRAMEBUFFER, buffer);
  7. GLuint attachments[4];
  8. u32 counter = 0;
  9. if(mode & POSITION) {
  10. glGenTextures(1, &(textures[0]));
  11. glBindTexture(GL_TEXTURE_2D, textures[0]);
  12. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, nullptr);
  13. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  14. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  15. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  16. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  17. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + counter, GL_TEXTURE_2D, textures[0], 0);
  18. attachments[counter] = GL_COLOR_ATTACHMENT0 + counter;
  19. counter++;
  20. }
  21. if(mode & NORMAL) {
  22. glGenTextures(1, &(textures[1]));
  23. glBindTexture(GL_TEXTURE_2D, textures[1]);
  24. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, nullptr);
  25. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  26. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  27. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  28. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  29. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + counter, GL_TEXTURE_2D, textures[1], 0);
  30. attachments[counter] = GL_COLOR_ATTACHMENT0 + counter;
  31. counter++;
  32. }
  33. if(mode & COLOR) {
  34. glGenTextures(1, &(textures[2]));
  35. glBindTexture(GL_TEXTURE_2D, textures[2]);
  36. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
  37. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  38. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  39. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  40. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  41. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + counter, GL_TEXTURE_2D, textures[2], 0);
  42. attachments[counter] = GL_COLOR_ATTACHMENT0 + counter;
  43. counter++;
  44. }
  45. if(mode & RED) {
  46. glGenTextures(1, &textures[3]);
  47. glBindTexture(GL_TEXTURE_2D, textures[3]);
  48. glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RGB, GL_FLOAT, nullptr);
  49. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  50. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  51. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  52. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  53. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + counter, GL_TEXTURE_2D, textures[3], 0);
  54. attachments[counter] = GL_COLOR_ATTACHMENT0 + counter;
  55. counter++;
  56. }
  57. if(mode & DEPTH24_STENCIL8) {
  58. glGenTextures(1, &textures[4]);
  59. glBindTexture(GL_TEXTURE_2D, textures[4]);
  60. glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, width, height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
  61. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  62. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  63. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  64. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  65. if(textureCompareFunc != 0) {
  66. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
  67. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, textureCompareFunc);
  68. }
  69. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, textures[4], 0);
  70. }
  71. glDrawBuffers(counter, attachments);
  72. if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
  73. std::cout << "frame buffer is not complete\n";
  74. return;
  75. }
  76. valid = true;
  77. }
  78. Framebuffer::~Framebuffer() {
  79. glDeleteFramebuffers(1, &buffer);
  80. for(GLuint& texture : textures) {
  81. glDeleteTextures(1, &texture);
  82. }
  83. }
  84. bool Framebuffer::isValid() const {
  85. return valid;
  86. }
  87. void Framebuffer::bind() const {
  88. glBindFramebuffer(GL_FRAMEBUFFER, buffer);
  89. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  90. }
  91. void Framebuffer::resize(u32 width, u32 height) const {
  92. if(mode & POSITION) {
  93. glBindTexture(GL_TEXTURE_2D, textures[0]);
  94. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, nullptr);
  95. }
  96. if(mode & NORMAL) {
  97. glBindTexture(GL_TEXTURE_2D, textures[1]);
  98. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, nullptr);
  99. }
  100. if(mode & COLOR) {
  101. glBindTexture(GL_TEXTURE_2D, textures[2]);
  102. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
  103. }
  104. if(mode & RED) {
  105. glBindTexture(GL_TEXTURE_2D, textures[3]);
  106. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RGB, GL_FLOAT, nullptr);
  107. }
  108. if(mode & DEPTH24_STENCIL8) {
  109. glBindTexture(GL_TEXTURE_2D, textures[4]);
  110. glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, width, height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
  111. }
  112. }
  113. void Framebuffer::bindPositionTexture(u32 textureUnit) const {
  114. glActiveTexture(GL_TEXTURE0 + textureUnit);
  115. glBindTexture(GL_TEXTURE_2D, textures[0]);
  116. }
  117. void Framebuffer::bindNormalTexture(u32 textureUnit) const {
  118. glActiveTexture(GL_TEXTURE0 + textureUnit);
  119. glBindTexture(GL_TEXTURE_2D, textures[1]);
  120. }
  121. void Framebuffer::bindColorTexture(u32 textureUnit) const {
  122. glActiveTexture(GL_TEXTURE0 + textureUnit);
  123. glBindTexture(GL_TEXTURE_2D, textures[2]);
  124. }
  125. void Framebuffer::bindRedTexture(u32 textureUnit) const {
  126. glActiveTexture(GL_TEXTURE0 + textureUnit);
  127. glBindTexture(GL_TEXTURE_2D, textures[3]);
  128. }
  129. void Framebuffer::bindDepthTexture(u32 textureUnit) const {
  130. glActiveTexture(GL_TEXTURE0 + textureUnit);
  131. glBindTexture(GL_TEXTURE_2D, textures[4]);
  132. }