FrameBufferObject.cpp
Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // File : FramebufferObject.h
00003 //------------------------------------------------------------------------------
00004 // Copyright (c) 2005 Gordon Wetzstein
00005 //---------------------------------------------------------------------------
00006 // This software is provided 'as-is', without any express or implied
00007 // warranty. In no event will the authors be held liable for any
00008 // damages arising from the use of this software.
00009 //
00010 // Permission is granted to anyone to use this software for any
00011 // purpose, including commercial applications, and to alter it and
00012 // redistribute it freely, subject to the following restrictions:
00013 //
00014 // 1. The origin of this software must not be misrepresented; you
00015 //    must not claim that you wrote the original software. If you use
00016 //    this software in a product, an acknowledgment in the product
00017 //    documentation would be appreciated but is not required.
00018 //
00019 // 2. Altered source versions must be plainly marked as such, and
00020 //    must not be misrepresented as being the original software.
00021 //
00022 // 3. This notice may not be removed or altered from any source
00023 //    distribution.
00024 //
00025 // -----------------------------------------------------------------------------
00026 //
00027 // Credits:
00028 // Original RenderTexture code: Mark J. Harris
00029 //      parts of the code are used from the original RenderTexture  
00030 //
00031 // -----------------------------------------------------------------------------
00032 
00033 #include "realtime_urdf_filter/FrameBufferObject.h"
00034 #include <stdio.h>
00035 #include <string.h>
00036 
00037 using namespace std;
00038 
00039 // -----------------------------------------------------------------------------
00040 
00042 int             _numInternal8AFormats           = 1;
00043 GLenum  _internal8AColorFormats[]       = {     GL_RGBA8 };
00045 int             _numInternal8Formats = 1;
00046 GLenum  _internal8ColorFormats[]        = {     GL_RGB8 };
00047 
00049 int                     _numInternal16AFormats  = 3;
00050 GLenum  _internal16AColorFormats[]      = {     GL_RGBA16F_ARB,
00051   GL_FLOAT_RGBA16_NV,
00052   GL_RGBA_FLOAT16_ATI   };
00053 
00055 int             _numInternal16Formats           = 3;
00056 GLenum  _internal16ColorFormats[]       = {     GL_RGB16F_ARB,
00057   GL_FLOAT_RGB16_NV,
00058   GL_RGB_FLOAT16_ATI    };
00059 
00061 int             _numInternal32AFormats          = 3;
00062 GLenum  _internal32AColorFormats[]      = {     GL_RGBA32F_ARB,
00063   GL_FLOAT_RGBA32_NV,
00064   GL_RGBA_FLOAT32_ATI   };
00065 
00067 int             _numInternal32Formats           = 3;
00068 GLenum  _internal32ColorFormats[]       = {     GL_RGB32F_ARB,
00069   GL_FLOAT_RGB32_NV,
00070   GL_RGB_FLOAT32_ATI    };
00071 
00072 GLenum _framebufferStatus;
00073 
00074 // -----------------------------------------------------------------------------
00075 
00076 FramebufferObject::FramebufferObject(const char *strMode) :
00077 
00078   _textureTarget(GL_TEXTURE_RECTANGLE_ARB),
00079   //_textureTarget(GL_TEXTURE_RECTANGLE_NV),
00080 
00081   _colorFormat(GL_RGBA),
00082   _internalColorFormat(GL_RGBA),
00083   _colorType(GL_UNSIGNED_BYTE),
00084 
00085   _colorAttachmentDepth(RGBA_8),
00086 
00087   _depthFormat(GL_DEPTH_COMPONENT),
00088   _internalDepthFormat(GL_DEPTH_COMPONENT24),
00089   _depthType(GL_UNSIGNED_BYTE),
00090 
00091   _wrapS(GL_CLAMP_TO_EDGE),
00092   _wrapT(GL_CLAMP_TO_EDGE),
00093   _minFilter(GL_LINEAR),
00094   _magFilter(GL_LINEAR),
00095 
00096   _width(512),
00097   _height(512),
00098 
00099   _bFBOSupported(false),
00100   _bInitialized(false),
00101 
00102   _bColorAttachment(false),
00103   _bColorAttachmentRenderTexture(false),
00104 
00105   _bDepthAttachment(false),
00106   _bDepthAttachmentRenderTexture(false),
00107 
00108   _bStencilAttachment(false),
00109   _bStencilAttachmentRenderTexture(false),
00110   _stencilDepth(1),
00111 
00112   // currently not used!
00113   _internalStencilFormat(GL_STENCIL_INDEX1),
00114 
00115   _bPassThroughProgramInitialized(false),
00116 
00117   _numColorAttachments(1),
00118 
00119   _bFloatColorBuffer(false)
00120 {
00121   parseModeString(strMode);
00122 }
00123 
00124 // -----------------------------------------------------------------------------
00125 
00126 FramebufferObject::~FramebufferObject() {
00127 
00128   if(_bInitialized) {
00129 
00130     if(_bColorAttachment) {
00131 
00132       for(int i=0; i<_numColorAttachments; i++) {
00133         if(_bColorAttachmentRenderTexture) 
00134           glDeleteTextures(1, &_colorAttachmentID[i]);
00135         else
00136           glDeleteRenderbuffers(1, &_colorAttachmentID[i]);
00137       }
00138     } 
00139 
00140     if(_bDepthAttachment) {
00141       if(_bDepthAttachmentRenderTexture) 
00142         glDeleteTextures(1, &_depthAttachmentID);
00143       else
00144         glDeleteRenderbuffers(1, &_depthAttachmentID);
00145     }
00146 
00147     glDeleteFramebuffers(1, &_frameBufferID);
00148 
00149   }
00150 
00151   if(_bPassThroughProgramInitialized)
00152     glDeleteProgramsARB(1, &_passThroughProgram); 
00153 }
00154 
00155 // -----------------------------------------------------------------------------
00156 
00157 unsigned int
00158 FramebufferObject::getWidth() {
00159   return _width;
00160 }
00161 
00162 // -----------------------------------------------------------------------------
00163 
00164 unsigned int
00165 FramebufferObject::getHeight() {
00166   return _height;
00167 }
00168 
00169 // -----------------------------------------------------------------------------
00170 
00171 void                                            
00172 FramebufferObject::bind(int index) {
00173   glEnable(_textureTarget);
00174   glBindTexture(_textureTarget, _colorAttachmentID[index]);
00175   glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00176   glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00177   glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00178   glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00179   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00180 }
00181 
00182 // -----------------------------------------------------------------------------
00183 
00184 void                                            
00185 FramebufferObject::bindDepth(void) {
00186   glEnable(_textureTarget);
00187   glBindTexture(_textureTarget, _depthAttachmentID);
00188   glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00189   glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00190   glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00191   glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00192   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00193 }
00194 
00195 // -----------------------------------------------------------------------------
00196 
00197 GLuint                                  
00198 FramebufferObject::getColorAttachmentID(int index) {
00199   return _colorAttachmentID[index];
00200 }
00201 
00202 // -----------------------------------------------------------------------------
00203 
00204 GLuint                                  
00205 FramebufferObject::getDepthAttachmentID(void) {
00206   return _depthAttachmentID;
00207 }
00208 
00209 // -----------------------------------------------------------------------------
00210 
00211 GLuint                                  
00212 FramebufferObject::getStencilAttachmentID(void) {
00213   return _depthAttachmentID;
00214 }
00215 
00216 // -----------------------------------------------------------------------------
00217 
00218 void                                            
00219 FramebufferObject::setMinFilter(GLint   minFilter) {
00220   _minFilter = minFilter;
00221 }
00222 
00223 // -----------------------------------------------------------------------------
00224 
00225 void                                            
00226 FramebufferObject::setMagFilter(GLint   magFilter) {
00227   _magFilter = magFilter;
00228 }
00229 
00230 // -----------------------------------------------------------------------------
00231 
00232 void                                            
00233 FramebufferObject::setWrapS(GLint       wrapS) {
00234   _wrapS = wrapS;
00235 }
00236 
00237 // -----------------------------------------------------------------------------
00238 
00239 void                                            
00240 FramebufferObject::setWrapT(GLint       wrapT) {
00241   _wrapT = wrapT;
00242 }
00243 
00244 // -----------------------------------------------------------------------------
00245 
00246 bool                                            
00247 FramebufferObject::initialize(  unsigned int width, unsigned int height ) {
00248 
00249   if(_bInitialized) 
00250     return reInitialize( width, height );
00251 
00252   _width        = width;
00253   _height = height;
00254 
00255 
00256   //if (!glh_init_extensions(   "GL_ARB_fragment_program "
00257   //                                                                                                    "GL_ARB_vertex_program "
00258   //                                                                                                    "GL_NV_float_buffer "
00259   //                                                                                                    "GL_ARB_framebuffer_object "))
00260   //{
00261   //            printf("Unable to load the following extension(s): %s\n\nExiting...\n", 
00262   //                                            glh_get_unsupported_extensions());
00263   //            return false;
00264   //}
00265 
00266   if(!GLEW_EXT_framebuffer_object)
00267     cout << "ERROR: FramebufferObject - GL_EXT_framebuffer_object not supported!" << endl;
00268 
00269   if(!GLEW_EXT_packed_depth_stencil)
00270     cout << "ERROR: FramebufferObject - GL_EXT_packed_depth_stencil not supported!" << endl;
00271 
00272   if(!GLEW_EXT_multi_draw_arrays)
00273     cout << "ERROR: FramebufferObject - GLEW_EXT_multi_draw_arrays not supported!" << endl;
00274 
00275   if(!GLEW_ARB_framebuffer_object)
00276     cout << "ERROR: FramebufferObject - GL_ARB_framebuffer_object not supported!" << endl;
00277 
00278   if(!GLEW_ARB_texture_non_power_of_two)
00279     cout << "ERROR: FramebufferObject - GL_ARB_texture_non_power_of_two not supported!" << endl;
00280 
00281 
00282   //---------------------------------------------------------------------
00283   //    create pass-throug programs
00284 
00285   if(!_bPassThroughProgramInitialized) {
00286 
00287     glGenProgramsARB(1, &_passThroughProgram);
00288 
00289     const char* strPassThroughProgram = 
00290       "!!ARBfp1.0\n"
00291       "MOV result.color, fragment.color.primary;\n"
00292       "END\n";
00293 
00294     glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _passThroughProgram);
00295     glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, 
00296         GL_PROGRAM_FORMAT_ASCII_ARB,
00297         strlen(strPassThroughProgram), 
00298         strPassThroughProgram);
00299 
00300     _bPassThroughProgramInitialized = true;
00301 
00302   }
00303 
00304   glGetIntegerv(GL_MAX_DRAW_BUFFERS, &_maxNumDrawBuffers);
00305   if(_numColorAttachments > _maxNumDrawBuffers) {
00306     cout << "WARNING: FramebufferObject::initialize - this machine only supports up to " << _maxNumDrawBuffers << " draw buffers. Reset number of color attachments!" << endl; 
00307     _numColorAttachments = _maxNumDrawBuffers;
00308   }
00309 
00310   //---------------------------------------------------------------------
00311 
00312   glPushAttrib(GL_TEXTURE_BIT);
00313 
00314   // create FBO
00315   glGenFramebuffers(1, &_frameBufferID);
00316   glBindFramebuffer(GL_FRAMEBUFFER, _frameBufferID);
00317 
00318   if(_bColorAttachment) {
00319 
00320     if(_bColorAttachmentRenderTexture) {
00321 
00322       int               count           = 0;
00323       bool      success = false;
00324 
00325       int                       numFormats = 1;
00326       GLenum    *format;
00327 
00328       switch(_colorAttachmentDepth) {
00329         case RGBA_8:
00330           numFormats    = _numInternal8AFormats;
00331           format                = _internal8AColorFormats;
00332           break;
00333         case RGB_8:
00334           numFormats    = _numInternal8Formats;
00335           format                = _internal8ColorFormats;
00336           break;                                                
00337         case RGBA_16:
00338           numFormats    = _numInternal16AFormats;
00339           format                = _internal16AColorFormats;
00340           break;
00341         case RGB_16:
00342           numFormats    = _numInternal16Formats;
00343           format                = _internal16ColorFormats;
00344           break;        
00345         case RGBA_32:
00346           numFormats    = _numInternal32AFormats;
00347           format                = _internal32AColorFormats;
00348           break;
00349         case RGB_32:
00350           numFormats    = _numInternal32Formats;
00351           format                = _internal32ColorFormats;
00352           break;                        
00353       }
00354 
00355       // initialize texture
00356       glEnable(_textureTarget);
00357       glGenTextures(1, &_colorAttachmentID[0]);
00358 
00359       do {
00360 
00361         _internalColorFormat = format[count];
00362 
00363         glBindTexture(_textureTarget, _colorAttachmentID[0]);
00364 
00365         glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00366         glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00367         glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00368         glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00369         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00370 
00371         glTexImage2D(   _textureTarget, 
00372             0, 
00373             _internalColorFormat, 
00374             _width, 
00375             _height, 
00376             0, 
00377             _colorFormat, 
00378             _colorType, 
00379             NULL);
00380 
00381         // attach texture to framebuffer color buffer
00382         glFramebufferTexture2D( GL_FRAMEBUFFER, 
00383             GL_COLOR_ATTACHMENT0, 
00384             _textureTarget,
00385             _colorAttachmentID[0], 
00386             0);
00387 
00388         success = checkFramebufferStatus();
00389         count++;
00390 
00391       } while( !(success || (count > (numFormats-1))) );
00392 
00393       //----------------------------------------------------------
00394       // initialize multiple render targets
00395 
00396       for(int i=1; i<_numColorAttachments; i++) {
00397 
00398         glGenTextures(1, &_colorAttachmentID[i]);
00399 
00400         glBindTexture(_textureTarget, _colorAttachmentID[i]);
00401 
00402         glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00403         glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00404         glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00405         glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00406         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00407 
00408         glTexImage2D(   _textureTarget, 
00409             0, 
00410             _internalColorFormat, 
00411             _width, 
00412             _height, 
00413             0, 
00414             _colorFormat, 
00415             _colorType, 
00416             NULL);
00417 
00418         GLint colorAttachmentMacro=GL_COLOR_ATTACHMENT0;
00419         switch(i) {
00420           case 1:
00421             colorAttachmentMacro=GL_COLOR_ATTACHMENT1;
00422             break;
00423           case 2:
00424             colorAttachmentMacro=GL_COLOR_ATTACHMENT2;
00425             break;
00426           case 3:
00427             colorAttachmentMacro=GL_COLOR_ATTACHMENT3;
00428             break;
00429           case 4:
00430             colorAttachmentMacro=GL_COLOR_ATTACHMENT4;
00431             break;
00432           case 5:
00433             colorAttachmentMacro=GL_COLOR_ATTACHMENT5;
00434             break;
00435           case 6:
00436             colorAttachmentMacro=GL_COLOR_ATTACHMENT6;
00437             break;
00438           case 7:
00439             colorAttachmentMacro=GL_COLOR_ATTACHMENT7;
00440             break;
00441           case 8:
00442             colorAttachmentMacro=GL_COLOR_ATTACHMENT8;
00443             break;
00444           case 9:
00445             colorAttachmentMacro=GL_COLOR_ATTACHMENT9;
00446             break;
00447           case 10:
00448             colorAttachmentMacro=GL_COLOR_ATTACHMENT10;
00449             break;
00450           case 11:
00451             colorAttachmentMacro=GL_COLOR_ATTACHMENT11;
00452             break;
00453           case 12:
00454             colorAttachmentMacro=GL_COLOR_ATTACHMENT12;
00455             break;
00456           case 13:
00457             colorAttachmentMacro=GL_COLOR_ATTACHMENT13;
00458             break;
00459           case 14:
00460             colorAttachmentMacro=GL_COLOR_ATTACHMENT14;
00461             break;
00462           case 15:
00463             colorAttachmentMacro=GL_COLOR_ATTACHMENT15;
00464             break;
00465         }
00466 
00467         // attach texture to framebuffer color buffer
00468         glFramebufferTexture2D( GL_FRAMEBUFFER, 
00469             colorAttachmentMacro, 
00470             _textureTarget,
00471             _colorAttachmentID[i], 
00472             0);
00473 
00474         success = checkFramebufferStatus();
00475         GLenum err = glGetError();
00476         if(err != GL_NO_ERROR)
00477           printf("OpenGL ERROR after FBO initialization: %s\n", gluErrorString(err));
00478 
00479       }
00480 
00481       //----------------------------------------------------------
00482 
00483       if(!success) 
00484         printFramebufferStatus();
00485 
00486     } else {
00487 
00488       //----------------------------------------------------------
00489       // initialize multiple render targets
00490 
00491       for(int i=0; i<_numColorAttachments; i++) {
00492 
00493         glGenRenderbuffers(1, &_colorAttachmentID[i]);
00494 
00495         // initialize color renderbuffer
00496         glBindRenderbuffer(GL_RENDERBUFFER, _colorAttachmentID[i]);
00497         glRenderbufferStorage(  GL_RENDERBUFFER, 
00498             _internalColorFormat,
00499             _width, 
00500             _height);
00501 
00502         GLint colorAttachmentMacro=GL_COLOR_ATTACHMENT0;
00503         switch(i) {
00504           case 1:
00505             colorAttachmentMacro=GL_COLOR_ATTACHMENT1;
00506             break;
00507           case 2:
00508             colorAttachmentMacro=GL_COLOR_ATTACHMENT2;
00509             break;
00510           case 3:
00511             colorAttachmentMacro=GL_COLOR_ATTACHMENT3;
00512             break;
00513           case 4:
00514             colorAttachmentMacro=GL_COLOR_ATTACHMENT4;
00515             break;
00516           case 5:
00517             colorAttachmentMacro=GL_COLOR_ATTACHMENT5;
00518             break;
00519           case 6:
00520             colorAttachmentMacro=GL_COLOR_ATTACHMENT6;
00521             break;
00522           case 7:
00523             colorAttachmentMacro=GL_COLOR_ATTACHMENT7;
00524             break;
00525           case 8:
00526             colorAttachmentMacro=GL_COLOR_ATTACHMENT8;
00527             break;
00528           case 9:
00529             colorAttachmentMacro=GL_COLOR_ATTACHMENT9;
00530             break;
00531           case 10:
00532             colorAttachmentMacro=GL_COLOR_ATTACHMENT10;
00533             break;
00534           case 11:
00535             colorAttachmentMacro=GL_COLOR_ATTACHMENT11;
00536             break;
00537           case 12:
00538             colorAttachmentMacro=GL_COLOR_ATTACHMENT12;
00539             break;
00540           case 13:
00541             colorAttachmentMacro=GL_COLOR_ATTACHMENT13;
00542             break;
00543           case 14:
00544             colorAttachmentMacro=GL_COLOR_ATTACHMENT14;
00545             break;
00546           case 15:
00547             colorAttachmentMacro=GL_COLOR_ATTACHMENT15;
00548             break;
00549         }
00550 
00551         // attach renderbuffer to framebuffer color buffer
00552         glFramebufferRenderbuffer(      GL_FRAMEBUFFER,
00553             colorAttachmentMacro,
00554             GL_RENDERBUFFER,
00555             _colorAttachmentID[i] );
00556 
00557       }
00558 
00559       //----------------------------------------------------------
00560 
00561       if(!checkFramebufferStatus())
00562         std::cerr<<"ERROR: "<<__FILE__<<":"<<__LINE__<<std::endl;
00563         printFramebufferStatus();
00564 
00565     }
00566 
00567   }
00568 
00569   //---------------------------------------------------------------------
00570   //---------------------------------------------------------------------
00571   //---------------------------------------------------------------------
00572   // depth attachment
00573 
00574   if(_bDepthAttachment) {
00575 
00576     if(_bStencilAttachment) {
00577 
00578       if(_internalDepthFormat != GL_DEPTH_COMPONENT24)
00579         cout << "WARNING: reset internal depth attachment format to 24 Bit [GL_DEPTH_STENCIL], otherwise stencil attachment won't work!" << endl;
00580 
00581       //std::cout<<"Using GL_DEPTH_COMPONENT24 for _internalDepthFormat."<<std::endl;
00582       _internalDepthFormat      = GL_DEPTH_COMPONENT24;
00583     }
00584 
00585     if(_bDepthAttachmentRenderTexture) {
00586 
00587       // initialize depth texture
00588       glGenTextures(1, &_depthAttachmentID);
00589       glBindTexture(_textureTarget, _depthAttachmentID);
00590 
00591       glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00592       glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00593       glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00594       glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00595       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00596 
00597       glTexImage2D(     _textureTarget, 
00598           0, 
00599           _internalDepthFormat, 
00600           _width, 
00601           _height, 
00602           0, 
00603           _depthFormat, 
00604           _depthType, 
00605           NULL);
00606 
00607       // attach texture to framebuffer color buffer
00608       glFramebufferTexture2D(
00609           GL_FRAMEBUFFER, 
00610           GL_DEPTH_ATTACHMENT, 
00611           _textureTarget,
00612           _depthAttachmentID, 0);
00613 
00614       if(!checkFramebufferStatus()) {
00615         std::cerr<<"ERROR: "<<__FILE__<<":"<<__LINE__<<std::endl;
00616         printFramebufferStatus();
00617       }
00618 
00619     } else {                            
00620 
00621       glGenRenderbuffers(1, &_depthAttachmentID);
00622 
00623       // initialize depth renderbuffer
00624       glBindRenderbuffer(GL_RENDERBUFFER, _depthAttachmentID);
00625       glRenderbufferStorage(    GL_RENDERBUFFER, 
00626           _internalDepthFormat,
00627           _width, 
00628           _height);
00629 
00630       // attach renderbuffer to framebuffer depth buffer
00631       glFramebufferRenderbuffer(        GL_FRAMEBUFFER,
00632           GL_DEPTH_ATTACHMENT,
00633           GL_RENDERBUFFER,
00634           _depthAttachmentID );
00635 
00636       if(!checkFramebufferStatus()) {
00637         std::cerr<<"ERROR: "<<__FILE__<<":"<<__LINE__<<std::endl;
00638         printFramebufferStatus();
00639       }
00640 
00641     }
00642 
00643   }
00644 
00645 
00646 
00647   //---------------------------------------------------------------------
00648   //---------------------------------------------------------------------
00649   //---------------------------------------------------------------------
00650   // stencil attachment
00651 
00652   if(_bStencilAttachment) {
00653 
00654     if(!_bDepthAttachment)
00655       cout << "ERROR: FBO stencil attachment is currently only supported in combination with a depth attachment: 24 Bit depth attachment + 8 Bit stencil attachment. See EXT_packed_depth_stencil specifications for details!" << endl;
00656 
00657     if(_bStencilAttachmentRenderTexture) {
00658 
00659       glBindTexture(_textureTarget, _depthAttachmentID);
00660 
00661       glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_S, _wrapS);
00662       glTexParameteri(_textureTarget, GL_TEXTURE_WRAP_T, _wrapT);
00663       glTexParameteri(_textureTarget, GL_TEXTURE_MIN_FILTER, _minFilter);
00664       glTexParameteri(_textureTarget, GL_TEXTURE_MAG_FILTER, _magFilter);
00665       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00666 
00667       glTexImage2D(     _textureTarget, 
00668           0, 
00669           _internalDepthFormat, 
00670           _width, 
00671           _height, 
00672           0, 
00673           _depthFormat, 
00674           _depthType, 
00675           NULL);
00676 
00677       // glBindTexture( _textureTarget, 0);
00678 
00679       // attach texture to framebuffer color buffer
00680       glFramebufferTexture2D(
00681           GL_FRAMEBUFFER, 
00682           GL_DEPTH_ATTACHMENT, 
00683           _textureTarget,
00684           _depthAttachmentID, 0);
00685 
00686       if(!checkFramebufferStatus()) {
00687         std::cerr<<"ERROR: "<<__FILE__<<":"<<__LINE__<<std::endl;
00688         printFramebufferStatus();
00689       }
00690 
00691     } else {
00692 
00693       // initialize depth renderbuffer
00694       glBindRenderbuffer(GL_RENDERBUFFER, _depthAttachmentID);
00695       glRenderbufferStorage(    GL_RENDERBUFFER, 
00696           _internalDepthFormat,
00697           _width, 
00698           _height);
00699 
00700       // attach renderbuffer to framebuffer depth buffer
00701       glFramebufferRenderbuffer(        GL_FRAMEBUFFER,
00702           GL_STENCIL_ATTACHMENT,
00703           GL_RENDERBUFFER,
00704           _depthAttachmentID );
00705 
00706       if(!checkFramebufferStatus()) {
00707         std::cerr<<"ERROR: "<<__FILE__<<":"<<__LINE__<<std::endl;
00708         printFramebufferStatus();
00709       }
00710 
00711     }
00712 
00713   }
00714 
00715 
00716   //---------------------------------------------------------------------
00717   //---------------------------------------------------------------------
00718   //---------------------------------------------------------------------
00719 
00720   // disable framebuffer again!
00721   glBindFramebuffer(GL_FRAMEBUFFER, 0);
00722 
00723   glPopAttrib();
00724 
00725   _bInitialized = true;
00726   _bFBOSupported = true;
00727 
00728   return true;
00729 }
00730 
00731 // -----------------------------------------------------------------------------
00732 
00733 bool                                            
00734 FramebufferObject::reInitialize(        unsigned int width, unsigned int height, const char *strMode ) {
00735 
00736   if(!_bInitialized) 
00737     return initialize( width, height );
00738 
00739   if(!_bFBOSupported)
00740     return false;
00741 
00742   // ---------------------------------------------------------
00743   // delete old configuration
00744 
00745   glDeleteFramebuffers(1, &_frameBufferID);
00746 
00747   if(_bColorAttachment) {
00748     if(_bColorAttachmentRenderTexture) 
00749       glDeleteTextures(1, &_colorAttachmentID[0]);
00750     else 
00751       glDeleteRenderbuffers(1, &_colorAttachmentID[0]);
00752   }
00753 
00754   if(_bDepthAttachment) {
00755     if(_bDepthAttachmentRenderTexture) 
00756       glDeleteTextures(1, &_depthAttachmentID);
00757     else
00758       glDeleteRenderbuffers(1, &_depthAttachmentID);
00759   }
00760 
00761   // ---------------------------------------------------------
00762 
00763   _bInitialized = false;
00764   parseModeString(strMode);
00765   initialize(width, height);
00766 
00767   return true;
00768 }
00769 
00770 // -----------------------------------------------------------------------------
00771 
00772 void                                            
00773 FramebufferObject::beginCapture(bool bEnablePassThroughShader) {
00774 
00775   glGetIntegerv(GL_VIEWPORT, _viewport);
00776   glViewport(0, 0, _width, _height);
00777 
00778   if(_bInitialized)
00779     glBindFramebuffer(GL_FRAMEBUFFER, _frameBufferID);
00780 
00781   if(_bFloatColorBuffer && bEnablePassThroughShader) {
00782     glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _passThroughProgram);
00783     glEnable(GL_FRAGMENT_PROGRAM_ARB);
00784   }             
00785 }
00786 
00787 // -----------------------------------------------------------------------------
00788 
00789 void                                            
00790 FramebufferObject::endCapture(bool bDisablePassThroughShader) {
00791 
00792   glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]);
00793 
00794   if(_bInitialized)
00795     glBindFramebuffer(GL_FRAMEBUFFER, 0);
00796 
00797   if(_bFloatColorBuffer && bDisablePassThroughShader) 
00798     glDisable(GL_FRAGMENT_PROGRAM_ARB);
00799 
00800 }
00801 
00802 // -----------------------------------------------------------------------------
00803 
00804 void                                            
00805 FramebufferObject::parseModeString(const char *modeString) {
00806 
00807   if (!modeString || strcmp(modeString, "") == 0)
00808     return;
00809 
00810   //int  iDepthBits             = 0;
00811   //bool bHasStencil    = false;
00812   //bool bBind2D                = false;
00813   //bool bBindRECT              = false;
00814   //bool bBindCUBE              = false;
00815 
00816   _bColorAttachment     = false;
00817   _bDepthAttachment     = false;
00818   _bStencilAttachment = false;
00819 
00820   _bFloatColorBuffer    = false;
00821 
00822   char *mode = strdup(modeString);
00823 
00824   vector<string> tokens;
00825   char *buf = strtok(mode, " ");
00826   while (buf != NULL)
00827   {
00828     tokens.push_back(buf);
00829     buf = strtok(NULL, " ");
00830   }
00831 
00832 
00833   for (unsigned int i = 0; i < tokens.size(); i++) {
00834 
00835     string token = tokens[i];
00836     KeyVal kv = getKeyValuePair(token);
00837 
00838     //cout << "Token: " << kv.first.c_str() << " = " << kv.second.c_str() << endl;
00839 
00840     // ------------------------------------------------
00841     // handle RGBA color attachment
00842     if ( strcmp(kv.first.c_str(), "rgba") == 0) {
00843 
00844       _bColorAttachment         = true;
00845       _colorFormat                      = GL_RGBA;
00846       _internalColorFormat      = GL_RGBA;
00847       _colorType                                = GL_UNSIGNED_BYTE;
00848       _colorAttachmentDepth     = RGBA_8;
00849 
00850       _minFilter                                = GL_LINEAR;
00851       _magFilter                                = GL_LINEAR;
00852 
00853       if( strchr(kv.second.c_str(), 't') != NULL ) {
00854         _bColorAttachmentRenderTexture = true;
00855       } else {
00856         _bColorAttachmentRenderTexture = false;
00857       }
00858 
00859       if( kv.second.find("16") != kv.second.npos ) {
00860 
00861         _colorAttachmentDepth = RGBA_16;
00862 
00863         _internalColorFormat    = GL_RGBA16F_ARB;
00864         _colorType                              = GL_HALF_FLOAT_ARB;
00865         _bFloatColorBuffer              = true;
00866 
00867       }
00868       if( kv.second.find("32") != kv.second.npos ) {
00869 
00870         _colorAttachmentDepth = RGBA_32;
00871 
00872         _internalColorFormat    = GL_RGBA32F_ARB;
00873         _colorType                              = GL_FLOAT;     
00874 
00875         // linear filter is not supported for 32 FBOs
00876         _minFilter                              = GL_NEAREST;
00877         _magFilter                              = GL_NEAREST;
00878 
00879         _bFloatColorBuffer              = true;
00880       }
00881 
00882       //---------------------------------------------   
00883       //        check for multiple render targets!
00884 
00885       if( kv.second.find("10x") != kv.second.npos ) {
00886         _numColorAttachments = 10;                              
00887       } else if( kv.second.find("11x") != kv.second.npos ) {
00888         _numColorAttachments = 11;                              
00889       } else if( kv.second.find("12x") != kv.second.npos ) {
00890         _numColorAttachments = 12;                              
00891       } else if( kv.second.find("13x") != kv.second.npos ) {
00892         _numColorAttachments = 13;                              
00893       } else if( kv.second.find("14x") != kv.second.npos ) {
00894         _numColorAttachments = 14;                              
00895       } else if( kv.second.find("15x") != kv.second.npos ) {
00896         _numColorAttachments = 15;                              
00897       } else if( kv.second.find("16x") != kv.second.npos ) {
00898         _numColorAttachments = 16;                              
00899       } else if( kv.second.find("2x") != kv.second.npos ) {
00900         _numColorAttachments = 2;                               
00901       } else if( kv.second.find("3x") != kv.second.npos ) {
00902         _numColorAttachments = 3;                               
00903       } else if( kv.second.find("4x") != kv.second.npos ) {
00904         _numColorAttachments = 4;                               
00905       } else if( kv.second.find("5x") != kv.second.npos ) {
00906         _numColorAttachments = 5;                               
00907       } else if( kv.second.find("6x") != kv.second.npos ) {
00908         _numColorAttachments = 6;                               
00909       } else if( kv.second.find("7x") != kv.second.npos ) {
00910         _numColorAttachments = 7;                               
00911       } else if( kv.second.find("8x") != kv.second.npos ) {
00912         _numColorAttachments = 8;                               
00913       } else if( kv.second.find("9x") != kv.second.npos ) {
00914         _numColorAttachments = 9;                               
00915       }  
00916 
00917       //---------------------------------------------
00918 
00919       // ------------------------------------------------
00920       // ------------------------------------------------
00921       // handle RGB color attachment
00922     } else if ( strcmp(kv.first.c_str(), "rgb") == 0) {
00923 
00924       _bColorAttachment                 = true;
00925       _colorFormat                              = GL_RGB;
00926       _internalColorFormat              = GL_RGB;
00927       _colorType                                        = GL_UNSIGNED_BYTE;
00928       _colorAttachmentDepth             = RGB_8;
00929 
00930       _minFilter                                        = GL_LINEAR;
00931       _magFilter                                        = GL_LINEAR;
00932 
00933       if( strchr(kv.second.c_str(), 't') != NULL ) {
00934         _bColorAttachmentRenderTexture = true;
00935       } else {
00936         _bColorAttachmentRenderTexture = false;
00937       }
00938 
00939       if( kv.second.find("16") != kv.second.npos ) {
00940 
00941         _internalColorFormat    = GL_RGB16F_ARB;
00942         _colorType                              = GL_HALF_FLOAT_ARB;
00943 
00944         _colorAttachmentDepth   = RGB_16;
00945         _bFloatColorBuffer              = true;
00946       }
00947       if( kv.second.find("32") != kv.second.npos ) {
00948 
00949         _internalColorFormat    = GL_RGB32F_ARB;
00950         _colorType                              = GL_FLOAT;
00951 
00952         // linear filter is not supported for 32 FBOs
00953         _minFilter                              = GL_NEAREST;
00954         _magFilter                              = GL_NEAREST;
00955 
00956         _colorAttachmentDepth = RGB_32;
00957         _bFloatColorBuffer              = true;
00958       }
00959 
00960       //---------------------------------------------   
00961       //        check for multiple render targets!
00962 
00963       if( kv.second.find("10x") != kv.second.npos ) {
00964         _numColorAttachments = 10;                              
00965       } else if( kv.second.find("11x") != kv.second.npos ) {
00966         _numColorAttachments = 11;                              
00967       } else if( kv.second.find("12x") != kv.second.npos ) {
00968         _numColorAttachments = 12;                              
00969       } else if( kv.second.find("13x") != kv.second.npos ) {
00970         _numColorAttachments = 13;                              
00971       } else if( kv.second.find("14x") != kv.second.npos ) {
00972         _numColorAttachments = 14;                              
00973       } else if( kv.second.find("15x") != kv.second.npos ) {
00974         _numColorAttachments = 15;                              
00975       } else if( kv.second.find("16x") != kv.second.npos ) {
00976         _numColorAttachments = 16;                              
00977       } else if( kv.second.find("2x") != kv.second.npos ) {
00978         _numColorAttachments = 2;                               
00979       } else if( kv.second.find("3x") != kv.second.npos ) {
00980         _numColorAttachments = 3;                               
00981       } else if( kv.second.find("4x") != kv.second.npos ) {
00982         _numColorAttachments = 4;                               
00983       } else if( kv.second.find("5x") != kv.second.npos ) {
00984         _numColorAttachments = 5;                               
00985       } else if( kv.second.find("6x") != kv.second.npos ) {
00986         _numColorAttachments = 6;                               
00987       } else if( kv.second.find("7x") != kv.second.npos ) {
00988         _numColorAttachments = 7;                               
00989       } else if( kv.second.find("8x") != kv.second.npos ) {
00990         _numColorAttachments = 8;                               
00991       } else if( kv.second.find("9x") != kv.second.npos ) {
00992         _numColorAttachments = 9;                               
00993       }  
00994 
00995       //---------------------------------------------
00996 
00997     }
00998 
00999     // ------------------------------------------------
01000     // ------------------------------------------------
01001     // handle depth attachment
01002 
01003     else if ( strcmp(kv.first.c_str(), "depth") == 0) {
01004 
01005       _bDepthAttachment         = true;
01006       _depthFormat                      = GL_DEPTH_COMPONENT;
01007       _depthType                                = GL_UNSIGNED_BYTE;
01008       /*TODO*/_depthType                                = GL_FLOAT;
01009       _internalDepthFormat      = GL_DEPTH_COMPONENT24;
01010 
01011       if( kv.second.find("t") != kv.second.npos ) {
01012         _bDepthAttachmentRenderTexture = true;
01013       } else {
01014         _bDepthAttachmentRenderTexture = false;
01015       }
01016 
01017       if( kv.second.find("16") != kv.second.npos ) 
01018         _internalDepthFormat    = GL_DEPTH_COMPONENT16;
01019       if( kv.second.find("24") != kv.second.npos ) 
01020         _internalDepthFormat    = GL_DEPTH_COMPONENT24;                          
01021       if( kv.second.find("32") != kv.second.npos ) 
01022         _internalDepthFormat    = GL_DEPTH_COMPONENT32;
01023     }
01024 
01025     // ------------------------------------------------
01026     // ------------------------------------------------
01027     // handle depth attachment
01028 
01029     else if ( strcmp(kv.first.c_str(), "stencil") == 0) {
01030 
01031       _bStencilAttachment = true;
01032 
01033       if( kv.second.find("t") != kv.second.npos ) {
01034         _bStencilAttachmentRenderTexture = true;
01035       } else {
01036         _bStencilAttachmentRenderTexture = false;
01037       }
01038 
01039       /*                        if( kv.second.find("16") != kv.second.npos ) {
01040               _stencilDepth     = 16;
01041               _internalStencilFormat = GL_STENCIL_INDEX16;
01042               } else if( kv.second.find("8") != kv.second.npos ) {
01043               _stencilDepth     = 8;
01044               _internalStencilFormat = GL_STENCIL_INDEX8;
01045               } else if( kv.second.find("4") != kv.second.npos ) {
01046               _stencilDepth     = 4;
01047               _internalStencilFormat = GL_STENCIL_INDEX4;
01048               } else if( kv.second.find("1") != kv.second.npos ) {
01049               _stencilDepth     = 1;
01050               _internalStencilFormat = GL_STENCIL_INDEX1;
01051               } */              
01052     }
01053 
01054   }
01055 }
01056 
01057 // -----------------------------------------------------------------------------
01058 
01059 FramebufferObject::KeyVal 
01060 FramebufferObject::getKeyValuePair(string token) {
01061 
01062   string::size_type pos = 0;
01063   if ((pos = token.find("=")) != token.npos) {
01064 
01065     string key = token.substr(0, pos);
01066     string value = token.substr(pos+1, token.length()-pos+1);
01067     return KeyVal(key, value);
01068   }
01069   else
01070     return KeyVal(token, "");
01071 }
01072 
01073 // -----------------------------------------------------------------------------
01074 
01075 bool 
01076 FramebufferObject::checkFramebufferStatus(void) {
01077 
01078   _framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
01079 
01080   if(_framebufferStatus == GL_FRAMEBUFFER_COMPLETE)
01081     return true;
01082   else
01083     return false;
01084 }
01085 
01086 // -----------------------------------------------------------------------------
01087 
01088 void
01089 FramebufferObject::printFramebufferStatus(void) {
01090 
01091   switch(_framebufferStatus) {
01092 
01093     case GL_FRAMEBUFFER_COMPLETE:
01094       cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_COMPLETE" << endl;
01095       break;
01096 
01097     case GL_FRAMEBUFFER_UNSUPPORTED:
01098       cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_UNSUPPORTED" << endl;
01099       break;
01100 
01101     case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 
01102       cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT" << endl;
01103       break; 
01104 
01105     case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 
01106       cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" << endl;
01107       break; 
01108 
01109     case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: 
01110       cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT" << endl;
01111       break; 
01112 
01113       //                case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT: 
01114       //                        cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT" << endl;
01115       //                        break; 
01116 
01117     case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: 
01118       cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT" << endl;
01119       break; 
01120 
01121     case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: 
01122       cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER" << endl;
01123       break; 
01124 
01125     case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: 
01126       cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER" << endl;
01127       break; 
01128 
01129     case GL_FRAMEBUFFER_BINDING: 
01130       cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_BINDING" << endl;
01131       break; 
01132 
01133       //                case GL_FRAMEBUFFER_STATUS_ERROR: 
01134       //                        cout << "FramebufferObject ERROR: GL_FRAMEBUFFER_STATUS_ERROR" << endl;
01135       //                        break; 
01136 
01137     default: 
01138       cout << "FramebufferObject ERROR: unidentified error!" << endl;
01139       break;
01140   }
01141 }
01142 
01143 // -----------------------------------------------------------------------------
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


realtime_urdf_filter
Author(s): Nico Blodow
autogenerated on Thu May 23 2013 16:50:36