Framebuffer.cpp 4.5 KB

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