Framebuffer.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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.width, size.height, attachments, counter);
  17. }
  18. }
  19. if(mode & DEPTH) {
  20. genTexture(4, size.width, size.height);
  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(int width, int height) 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, width, height, 0, data[i].format, data[i].type, nullptr);
  53. }
  54. }
  55. }
  56. void Framebuffer::bindTexture(int textureUnit, GLuint texture) const {
  57. glActiveTexture(GL_TEXTURE0 + textureUnit);
  58. glBindTexture(GL_TEXTURE_2D, texture);
  59. }
  60. void Framebuffer::bindPositionTexture(int textureUnit) const {
  61. bindTexture(textureUnit, textures[0]);
  62. }
  63. void Framebuffer::bindNormalTexture(int textureUnit) const {
  64. bindTexture(textureUnit, textures[1]);
  65. }
  66. void Framebuffer::bindColorTexture(int textureUnit) const {
  67. bindTexture(textureUnit, textures[2]);
  68. }
  69. void Framebuffer::bindRedTexture(int textureUnit) const {
  70. bindTexture(textureUnit, textures[3]);
  71. }
  72. void Framebuffer::bindDepthTexture(int textureUnit) const {
  73. bindTexture(textureUnit, textures[4]);
  74. }
  75. void Framebuffer::genTexture(int index, int width, int height) {
  76. glGenTextures(1, &(textures[index]));
  77. glBindTexture(GL_TEXTURE_2D, textures[index]);
  78. glTexImage2D(GL_TEXTURE_2D, 0, data[index].internalFormat, width, height, 0, data[index].format, data[index].type, nullptr);
  79. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  80. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  81. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  82. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  83. }
  84. void Framebuffer::setupTexture(int index, int width, int height, GLuint* attachments, int& counter) {
  85. genTexture(index, width, height);
  86. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + counter, GL_TEXTURE_2D, textures[index], 0);
  87. attachments[counter] = GL_COLOR_ATTACHMENT0 + counter;
  88. counter++;
  89. }
  90. const char* Framebuffer::getErrorString(GLenum error) const {
  91. switch(error) {
  92. case GL_FRAMEBUFFER_UNDEFINED: return "GL_FRAMEBUFFER_UNDEFINED";
  93. case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
  94. case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
  95. case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: return "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER";
  96. case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: return "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER";
  97. case GL_FRAMEBUFFER_UNSUPPORTED: return "GL_FRAMEBUFFER_UNSUPPORTED";
  98. case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: return "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
  99. case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: return "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS";
  100. }
  101. return "unknown error";
  102. }