Framebuffer.cpp 6.4 KB

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