Advertisement
Caiwan

fbo.cpp

Sep 24th, 2012
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.86 KB | None | 0 0
  1. #include "extensions.h"
  2. #include "bufferObject.h"
  3.  
  4. #include "../debug/errors.h"
  5. #include "../math/matrix.h"
  6. #include "../core/core.h"
  7.  
  8. #include <cstdlib>
  9.  
  10. //-----------------------------------------------------------------------------------------------------------------------
  11.  
  12. /*
  13.     * Frame buffer/ render buffer class
  14.     * ---------------------------------
  15.     *
  16. */
  17. namespace {
  18.     bool using_fbo = false;
  19.  
  20.     void checkIsFBOAvailable(){
  21.         if (glGenFramebuffersEXT)
  22.             using_fbo = true;
  23.         else
  24.             using_fbo = false;
  25.     }
  26.  
  27.     bool checkFBOStatus(){
  28.          // check FBO status
  29.         GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  30.         //using_fbo = false;
  31. #if defined (CORE_DUMPING) && defined (CORE_DEBUG)
  32.         switch(status)
  33.         {
  34.         //case GL_FRAMEBUFFER_COMPLETE:
  35.         case GL_FRAMEBUFFER_COMPLETE_EXT:
  36.             //fprintf(_STDOUT, "Framebuffer complete. \n" );    fflush(_STDOUT);
  37.             return true;
  38.             //break;
  39.  
  40.         //case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
  41.         case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
  42.             fprintf(_STDOUT, "[ERROR] Framebuffer incomplete: Attachment is NOT complete." );   fflush(_STDOUT);
  43.             return false;
  44.  
  45.         //case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
  46.         case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
  47.             fprintf(_STDOUT, "[ERROR] Framebuffer incomplete: No image is attached to FBO." );  fflush(_STDOUT);
  48.             return false;
  49.  
  50.         //case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
  51.         case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
  52.             fprintf(_STDOUT, "[ERROR] Framebuffer incomplete: Attached images have different dimensions." );    fflush(_STDOUT);
  53.             return false;
  54.  
  55.         //case GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
  56.         case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
  57.             fprintf(_STDOUT, "[ERROR] Framebuffer incomplete: Color attached images have different internal formats." );    fflush(_STDOUT);
  58.             return false;
  59.  
  60.         //case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
  61.         case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
  62.             fprintf(_STDOUT, "[ERROR] Framebuffer incomplete: Draw buffer." );  fflush(_STDOUT);
  63.             return false;
  64.  
  65.         //case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
  66.         case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
  67.             fprintf(_STDOUT, "[ERROR] Framebuffer incomplete: Read buffer." );  fflush(_STDOUT);
  68.             return false;
  69.  
  70.         //case GL_FRAMEBUFFER_UNSUPPORTED:
  71.         case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
  72.             fprintf(_STDOUT, "[ERROR] Unsupported by FBO implementation." );    fflush(_STDOUT);
  73.             return false;
  74.  
  75.         default:
  76.             fprintf(_STDOUT, "[ERROR] Unknown error." );    fflush(_STDOUT);
  77.             return false;
  78.         }
  79. #else
  80.     if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
  81.         return false;
  82. #endif
  83.     //checkIsFBOAvailable();
  84.     return true;
  85.     }
  86. }
  87.  
  88. FWrender::fbo::fbo(int colorMapNum, int depthMap, int stencilMap, bool _isCreateMipmap)
  89. {
  90.     this->isGenerateMipmap = _isCreateMipmap;
  91.     this->renderColor = (unsigned int)(colorMapNum)%15;
  92.    
  93.     this->renderDepth = (depthMap != 0);
  94.     this->renderStencil = (stencilMap != 0);
  95.  
  96.     this->tex = new FWrender::texture*[colorMapNum];
  97.     for (int i=0; i<colorMapNum; i++){
  98.         this->tex[i] = new FWrender::texture();
  99.         this->tex[i]->props.textureFormat = FWrender::TFM_RGBA;
  100.         this->tex[i]->props.dataFormat = FWrender::TDT_UNSIGNED_BYTE;
  101.         this->tex[i]->props.generateMipmap = _isCreateMipmap;
  102.         if (_isCreateMipmap){
  103.             this->tex[i]->props.magFilter = FWrender::TF_LINEAR;
  104.             this->tex[i]->props.minFilter = FWrender::TF_LINEAR_MIPMAP_LINEAR;
  105.         }
  106.         this->tex[i]->setSize(RENDERER_RENDERBUFFER_SIZE, RENDERER_RENDERBUFFER_SIZE);
  107.         this->tex[i]->buildEmpty();
  108.     }
  109.  
  110.     if (this->renderDepth){
  111.         this->depthTex = new FWrender::texture();
  112.         this->depthTex->props.depthMode = 1;
  113.         this->depthTex->props.textureFormat = FWrender::TFM_DEPTH_COMPONENT;
  114.         this->depthTex->props.dataFormat = FWrender::TDT_UNSIGNED_INT;
  115.         this->depthTex->setSize(RENDERER_RENDERBUFFER_SIZE, RENDERER_RENDERBUFFER_SIZE);
  116.         this->depthTex->buildEmpty();
  117.     }
  118.  
  119.     // render stencil
  120.  
  121.     this->drawBufferList = new GLuint[this->renderColor];
  122.  
  123. #if defined (CORE_DUMPING) && defined (CORE_DEBUG)
  124.     fprintf(_STDOUT, "FBO: Generating %d color, %d depth, %d stencil map(s) \n", this->renderColor, this->renderDepth, this->renderStencil);
  125.     fflush(_STDOUT);
  126. #endif
  127.  
  128.     checkIsFBOAvailable();
  129.     if (using_fbo)
  130.         init();
  131.     else
  132.         FWcore::releaseFw(1);
  133. }
  134.  
  135. void FWrender::fbo::init(){
  136.     this->fbo_id = 0;
  137.  
  138.     this->rbo_id = NULL;
  139.     this->rbo_DepthID = 0;
  140.     this->rbo_StencilID = 0;
  141.    
  142.     //unsigned int spp = FWrender::getSamplePerPixel();
  143.     unsigned int spp = 1;
  144.     //GLuint attachment;
  145.  
  146.     //if (!this->renderColor) return;
  147.  
  148.     glGenFramebuffersEXT(1, (GLuint*)&fbo_id);
  149.     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (GLuint)fbo_id);
  150.  
  151.     if (this->renderColor) {
  152.         this->rbo_id = new int [this->renderColor];
  153.  
  154.         for (int i=0; i<this->renderColor; i++) {
  155.             glGenRenderbuffersEXT(1, (GLuint*)&rbo_id[i]);
  156.             glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, (GLuint)rbo_id[i]);
  157.             // attach depth component due to depth test.
  158.            
  159.             if (spp>1) glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, spp, GL_RGBA8, this->tex[i]->props.sizeX, this->tex[i]->props.sizeY);
  160.  
  161.             if (i)
  162.                 if (spp>1)
  163.                     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, spp, GL_DEPTH_COMPONENT32, this->tex[i]->props.sizeX, this->tex[i]->props.sizeY);
  164.                 else
  165.                     glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, this->tex[i]->props.sizeX, this->tex[i]->props.sizeY);
  166.             if (i) glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
  167.  
  168.             glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_TEXTURE_2D, this->tex[i]->getID(), 0);
  169.  
  170.             this->drawBufferList[i] = GL_COLOR_ATTACHMENT0_EXT+i;
  171.  
  172.             //glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_RENDERBUFFER_EXT, (GLuint)rbo_id[i]);
  173.             if (i) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, (GLuint)rbo_id[i]);
  174.            
  175.             bool status = checkFBOStatus(); using_fbo = status;
  176.             if (!status) FWcore::releaseFw(1);
  177.  
  178.             //glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
  179.         }
  180.     }
  181.  
  182.     if (this->renderDepth) {
  183.         //this->rbo_DepthID = 0;
  184.         glGenRenderbuffersEXT(1, (GLuint*)&this->rbo_DepthID);
  185.         glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, (GLuint)this->rbo_DepthID);
  186.         //glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->depthTex->props.sizeX, this->depthTex->props.sizeY);
  187.         if (spp>1)
  188.             glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, spp, GL_DEPTH_COMPONENT32, this->depthTex->props.sizeX, this->depthTex->props.sizeY);
  189.         else
  190.             glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, this->depthTex->props.sizeX, this->depthTex->props.sizeY);
  191.         glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
  192.        
  193.         glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, (GLuint)this->depthTex->getID(), 0);
  194.  
  195.         //glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, (GLuint)this->rbo_DepthID);
  196.     }      
  197.    
  198.     if (this->renderColor)
  199.         glDrawBuffers(this->renderColor, this->drawBufferList);
  200.     else{
  201.         glDrawBuffer(GL_NONE);
  202.         glReadBuffer(GL_NONE);
  203.     }
  204.  
  205.     bool status = checkFBOStatus(); using_fbo = status;
  206.     if (!status) FWcore::releaseFw(1);
  207.  
  208.     glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
  209.     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  210. }
  211.  
  212. FWrender::fbo::~fbo(){
  213.     if (!using_fbo) return;
  214.     glDeleteFramebuffersEXT(1, (GLuint*)&fbo_id);
  215.     glDeleteRenderbuffersEXT(1, (GLuint*)&rbo_id);
  216.  
  217.     //if (this->tex) delete this->tex;  // hm
  218.  
  219.     // TODO: DESTRUCT
  220. }
  221.  
  222. void FWrender::fbo::bind(){
  223.    
  224.     //glPixelTransferf(GL_DEPTH_SCALE, 10);
  225.     //int e = glGetError();
  226.     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->fbo_id);
  227.     //int e = glGetError();
  228. }
  229.  
  230. void FWrender::fbo::unbind(){
  231.     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  232.    
  233.     if (this->isGenerateMipmap) for (int i=0; i<this->renderColor; i++){
  234.         this->tex[i]->bind();
  235.         glGenerateMipmapEXT(GL_TEXTURE_2D);
  236.         this->tex[i]->unbind();
  237.     }
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement