Framebuffer.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include <iostream>
  2. #include "client/rendering/wrapper/Framebuffer.h"
  3. Framebuffer::Framebuffer(const WindowSize& size, uint mode, bool texCompare) : mode(mode), textures(0),
  4. buffer(0), error(false) {
  5. glGenFramebuffers(1, &buffer);
  6. glBindFramebuffer(GL_FRAMEBUFFER, buffer);
  7. data[0] = {POSITION, GL_RGB16F, GL_RGB, GL_FLOAT};
  8. data[1] = {NORMAL, GL_RGB16F, GL_RGB, GL_FLOAT};
  9. data[2] = {COLOR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE};
  10. data[3] = {RED, GL_R32F, GL_RGB, GL_FLOAT};
  11. data[4] = {TANGENT, GL_RGB16F, GL_RGB, GL_FLOAT};
  12. data[5] = {DEPTH, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT};
  13. GLuint attachments[5];
  14. uint counter = 0;
  15. for(uint i = 0; i < 5; i++) {
  16. if(mode & data[i].mask) {
  17. setupTexture(i, size.width, size.height, attachments, counter);
  18. }
  19. }
  20. if(mode & DEPTH) {
  21. genTexture(5, size.width, size.height);
  22. if(texCompare) {
  23. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
  24. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
  25. }
  26. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textures[5], 0);
  27. }
  28. glDrawBuffers(counter, attachments);
  29. GLenum glError = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  30. if(glError != GL_FRAMEBUFFER_COMPLETE) {
  31. std::cout << "frame buffer error: " << getErrorString(error) << "\n";
  32. error = true;
  33. }
  34. }
  35. Framebuffer::~Framebuffer() {
  36. glDeleteFramebuffers(1, &buffer);
  37. for(GLuint& texture : textures) {
  38. glDeleteTextures(1, &texture);
  39. }
  40. }
  41. bool Framebuffer::hasError() const {
  42. return error;
  43. }
  44. void Framebuffer::bind() const {
  45. glBindFramebuffer(GL_FRAMEBUFFER, buffer);
  46. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  47. }
  48. void Framebuffer::resize(uint width, uint height) const {
  49. for(uint i = 0; i < 6; i++) {
  50. if(mode & data[i].mask) {
  51. glBindTexture(GL_TEXTURE_2D, textures[i]);
  52. glTexImage2D(GL_TEXTURE_2D, 0, data[i].internalFormat, width, height, 0, data[i].format, data[i].type, nullptr);
  53. }
  54. }
  55. }
  56. void Framebuffer::bindTexture(uint textureUnit, GLuint texture) const {
  57. glActiveTexture(GL_TEXTURE0 + textureUnit);
  58. glBindTexture(GL_TEXTURE_2D, texture);
  59. }
  60. void Framebuffer::bindPositionTexture(uint textureUnit) const {
  61. bindTexture(textureUnit, textures[0]);
  62. }
  63. void Framebuffer::bindNormalTexture(uint textureUnit) const {
  64. bindTexture(textureUnit, textures[1]);
  65. }
  66. void Framebuffer::bindColorTexture(uint textureUnit) const {
  67. bindTexture(textureUnit, textures[2]);
  68. }
  69. void Framebuffer::bindRedTexture(uint textureUnit) const {
  70. bindTexture(textureUnit, textures[3]);
  71. }
  72. void Framebuffer::bindTangentTexture(uint textureUnit) const {
  73. bindTexture(textureUnit, textures[4]);
  74. }
  75. void Framebuffer::bindDepthTexture(uint textureUnit) const {
  76. bindTexture(textureUnit, textures[5]);
  77. }
  78. void Framebuffer::genTexture(uint index, uint width, uint height) {
  79. glGenTextures(1, textures + index);
  80. glBindTexture(GL_TEXTURE_2D, textures[index]);
  81. glTexImage2D(GL_TEXTURE_2D, 0, data[index].internalFormat, width, height, 0, data[index].format, data[index].type, nullptr);
  82. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  83. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  84. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  85. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  86. }
  87. void Framebuffer::setupTexture(uint index, uint width, uint height, GLuint* attachments, uint& counter) {
  88. genTexture(index, width, height);
  89. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + counter, GL_TEXTURE_2D, textures[index], 0);
  90. attachments[counter] = GL_COLOR_ATTACHMENT0 + counter;
  91. counter++;
  92. }
  93. const char* Framebuffer::getErrorString(GLenum error) const {
  94. switch(error) {
  95. case GL_FRAMEBUFFER_UNDEFINED: return "GL_FRAMEBUFFER_UNDEFINED";
  96. case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
  97. case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
  98. case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: return "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER";
  99. case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: return "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER";
  100. case GL_FRAMEBUFFER_UNSUPPORTED: return "GL_FRAMEBUFFER_UNSUPPORTED";
  101. case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: return "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
  102. case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: return "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS";
  103. }
  104. return "unknown error";
  105. }