# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlGraphics/FramebufferObject.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    00029 /*                                                                                    */
    00030 /**************************************************************************************/
    00031
    00032 #include <vlCore/VisualizationLibrary.hpp>
    00033 #include <vlGraphics/FramebufferObject.hpp>
    00034 #include <vlGraphics/OpenGLContext.hpp>
    00035 #include <vlCore/VLSettings.hpp>
    00036 #include <vlCore/Say.hpp>
    00037 #include <vlCore/Log.hpp>
    00038
    00039 using namespace vl;
    00040
    00041 namespace
    00042 {
    00043   class ScopedFBOBinding
    00044   {
    00045     GLint mPrevFBO;
    00046   public:
    00047     ScopedFBOBinding( FBORenderTarget* fbo )
    00048     {
    00049       VL_CHECK( fbo );
    00050       VL_CHECK( fbo->handle() );
    00051       /*if ( !fbo->handle() )
    00052         fbo->create();*/
    00053
    00054       // saves current FBO
    00055       mPrevFBO = 0;
    00056       glGetIntegerv( GL_FRAMEBUFFER_BINDING, &mPrevFBO ); VL_CHECK_OGL()
    00057
    00058       // binds this FBO
    00059       VL_glBindFramebuffer( GL_FRAMEBUFFER, fbo->handle() ); VL_CHECK_OGL()
    00060     }
    00061
    00062     ~ScopedFBOBinding()
    00063     {
    00064       // restore the FBO
    00065       VL_glBindFramebuffer( GL_FRAMEBUFFER, mPrevFBO ); VL_CHECK_OGL()
    00066     }
    00067   };
    00068 }
    00069 //-----------------------------------------------------------------------------
    00070 // FBORenderTarget
    00071 //-----------------------------------------------------------------------------
    00072 void FBORenderTarget::create()
    00073 {
    00074   VL_CHECK_OGL();
    00075   VL_CHECK(openglContext());
    00076   openglContext()->makeCurrent(); VL_CHECK_OGL();
    00077
    00078   if ( !mHandle )
    00079   {
    00080     VL_glGenFramebuffers( 1, ( unsigned int* )&mHandle ); VL_CHECK_OGL();
    00081   }
    00082   VL_CHECK( mHandle )
    00083 }
    00084 //-----------------------------------------------------------------------------
    00085 void FBORenderTarget::destroy()
    00086 {
    00087   VL_CHECK_OGL();
    00088   VL_CHECK(openglContext());
    00089   openglContext()->makeCurrent(); VL_CHECK_OGL();
    00090
    00091   removeAllAttachments();
    00092   if ( handle() )
    00093   {
    00094     VL_glBindFramebuffer( GL_FRAMEBUFFER, 0 ); VL_CHECK_OGL();
    00095     VL_glDeleteFramebuffers( 1, &mHandle ); VL_CHECK_OGL();
    00096     mHandle = 0;
    00097   }
    00098   setWidth( 0 );
    00099   setHeight( 0 );
    00100 }
    00101 //-----------------------------------------------------------------------------
    00102 void FBORenderTarget::bindFramebuffer( EFrameBufferBind target )
    00103 {
    00104   VL_CHECK_OGL();
    00105   VL_CHECK(openglContext());
    00106   openglContext()->makeCurrent(); VL_CHECK_OGL();
    00107
    00108   if ( !GLEW_Has_Framebuffer_Object )
    00109   {
    00110     Log::error( "FBORenderTarget::bindFramebuffer(): framebuffer object not supported.\n" );
    00111     return;
    00112   }
    00113
    00114   if ( width() <= 0 || height() <= 0 )
    00115   {
    00116     Log::error( Say( "FBORenderTarget::bindFramebuffer() called with illegal dimensions: width = %n, height = %n\n" ) << width() << height() );
    00117     VL_TRAP()
    00118   }
    00119
    00120   if ( mFBOAttachments.empty() )
    00121   {
    00122     Log::error( "FBORenderTarget::bindFramebuffer() called with no attachment points!\n" );
    00123     VL_TRAP()
    00124   }
    00125
    00126   if ( !handle() )
    00127   {
    00128     Log::error( "FBORenderTarget::bindFramebuffer() called but handle() == NULL!\n" );
    00129     VL_TRAP()
    00130   }
    00131
    00132   VL_glBindFramebuffer( target, handle() ); VL_CHECK_OGL()
    00133
    00134   // bind draw buffers
    00135   if (target == FBB_FRAMEBUFFER || target == FBB_DRAW_FRAMEBUFFER)
    00136     bindDrawBuffers();
    00137
    00138   // bind read buffer
    00139   if (target == FBB_FRAMEBUFFER || target == FBB_READ_FRAMEBUFFER)
    00140     bindReadBuffer();
    00141
    00142   #ifndef NDEBUG
    00143     GLenum status = VL_glCheckFramebufferStatus( GL_FRAMEBUFFER ); VL_CHECK_OGL()
    00144     if ( status != GL_FRAMEBUFFER_COMPLETE )
    00145     {
    00146       VL_glBindFramebuffer( GL_FRAMEBUFFER, 0 ); VL_CHECK_OGL()
    00147     }
    00148     printFramebufferError( status );
    00149   #endif
    00150 }
    00151 //-----------------------------------------------------------------------------
    00153 GLenum FBORenderTarget::checkFramebufferStatus()
    00154 {
    00155   VL_CHECK_OGL();
    00156   VL_CHECK(openglContext());
    00157   openglContext()->makeCurrent(); VL_CHECK_OGL();
    00158
    00159   if ( !GLEW_Has_Framebuffer_Object )
    00160   {
    00161     Log::error( "FBORenderTarget::checkFramebufferStatus(): framebuffer object not supported.\n" );
    00162     return 0;
    00163   }
    00164
    00165   if ( width() <= 0 || height() <= 0 )
    00166   {
    00167     Log::error( Say( "FBORenderTarget::checkFramebufferStatus() called with illegal dimensions: width = %n, height = %n\n" ) << width() << height() );
    00168     return 0;
    00169   }
    00170
    00171   if ( mFBOAttachments.empty() )
    00172   {
    00173     Log::error( "FBORenderTarget::checkFramebufferStatus() called with no attachment points!\n" );
    00174     return 0;
    00175   }
    00176
    00177   if ( !handle() )
    00178   {
    00179     Log::error( "FBORenderTarget::checkFramebufferStatus() called but handle() == NULL!\n" );
    00180     return 0;
    00181   }
    00182
    00183   // binds the FBO for this function call
    00184   ScopedFBOBinding fbo_bind( this );
    00185
    00186   // checks error
    00187   GLenum status = VL_glCheckFramebufferStatus( GL_FRAMEBUFFER ); VL_CHECK_OGL()
    00188
    00189   // restore the FBO
    00190   if ( globalSettings()->verbosityLevel() >= vl::VEL_VERBOSITY_NORMAL )
    00191     printFramebufferError( status );
    00192
    00193   VL_CHECK( status == GL_FRAMEBUFFER_COMPLETE )
    00194
    00195   return status;
    00196 }
    00197 //-----------------------------------------------------------------------------
    00198 void FBORenderTarget::printFramebufferError( GLenum status ) const
    00199 {
    00200   switch( status )
    00201   {
    00202   case GL_FRAMEBUFFER_COMPLETE:
    00203     break;
    00204   case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
    00205     Log::bug( "FBORenderTarget::activate(): GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n" ); VL_TRAP()
    00206     break;
    00207   case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
    00208     Log::bug( "FBORenderTarget::activate(): GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n" ); VL_TRAP()
    00209     break;
    00210   case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
    00211     Log::bug( "FBORenderTarget::activate(): GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n" ); VL_TRAP()
    00212     break;
    00213   case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
    00214     Log::bug( "FBORenderTarget::activate(): GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n" ); VL_TRAP()
    00215     break;
    00216   case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
    00217     Log::bug( "FBORenderTarget::activate(): GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\n" ); VL_TRAP()
    00218     break;
    00219   case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
    00220     Log::bug( "FBORenderTarget::activate(): GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\n" ); VL_TRAP()
    00221     break;
    00222   case GL_FRAMEBUFFER_UNSUPPORTED:
    00223     Log::bug( "FBORenderTarget::activate(): GL_FRAMEBUFFER_UNSUPPORTED\n" ); VL_TRAP()
    00224     break;
    00225   case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB:
    00226     Log::bug( "FBORenderTarget::activate(): GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB\n" ); VL_TRAP()
    00227     break;
    00228   case GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB:
    00229     Log::bug( "FBORenderTarget::activate(): GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB\n" ); VL_TRAP()
    00230     break;
    00231   case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
    00232     Log::bug( "FBORenderTarget::activate(): GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\n" ); VL_TRAP()
    00233     break;
    00234   }
    00235 }
    00236 //-----------------------------------------------------------------------------
    00237 void FBORenderTarget::addColorAttachment( EAttachmentPoint attach_point, FBOColorBufferAttachment* attachment )
    00238 {
    00239   VL_CHECK( attach_point >= AP_COLOR_ATTACHMENT0 && attach_point <= AP_COLOR_ATTACHMENT15 );
    00240   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00241   if( !GLEW_Has_Framebuffer_Object )
    00242     return;
    00243   removeAttachment( attach_point );
    00244   mFBOAttachments[attach_point] = attachment;
    00245   attachment->mFBORenderTargets.insert( this );
    00246   attachment->bindAttachment( this, attach_point );
    00247 }
    00248 //-----------------------------------------------------------------------------
    00249 void FBORenderTarget::addTextureAttachment( EAttachmentPoint attach_point, FBOAbstractTextureAttachment* attachment )
    00250 {
    00251   VL_CHECK( attach_point >= AP_COLOR_ATTACHMENT0 && attach_point <= AP_COLOR_ATTACHMENT15 );
    00252   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00253   if( !GLEW_Has_Framebuffer_Object )
    00254     return;
    00255   removeAttachment( attach_point );
    00256   mFBOAttachments[attach_point] = attachment;
    00257   attachment->mFBORenderTargets.insert( this );
    00258   attachment->bindAttachment( this, attach_point );
    00259 }
    00260 //-----------------------------------------------------------------------------
    00261 void FBORenderTarget::addDepthAttachment( FBOAbstractAttachment* attachment )
    00262 {
    00263   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00264   if( !GLEW_Has_Framebuffer_Object )
    00265     return;
    00266   removeAttachment( AP_DEPTH_ATTACHMENT );
    00267   mFBOAttachments[AP_DEPTH_ATTACHMENT] = attachment;
    00268   attachment->mFBORenderTargets.insert( this );
    00269   attachment->bindAttachment( this, AP_DEPTH_ATTACHMENT );
    00270 }
    00271 //-----------------------------------------------------------------------------
    00272 void FBORenderTarget::addStencilAttachment( FBOAbstractAttachment* attachment )
    00273 {
    00274   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00275   if( !GLEW_Has_Framebuffer_Object )
    00276     return;
    00277   removeAttachment( AP_STENCIL_ATTACHMENT );
    00278   mFBOAttachments[AP_STENCIL_ATTACHMENT] = attachment;
    00279   attachment->mFBORenderTargets.insert( this );
    00280   attachment->bindAttachment( this, AP_STENCIL_ATTACHMENT );
    00281 }
    00282 //-----------------------------------------------------------------------------
    00283 void FBORenderTarget::addDepthStencilAttachment( FBOAbstractAttachment* attachment )
    00284 {
    00285   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00286   if( !GLEW_Has_Framebuffer_Object )
    00287     return;
    00288   removeAttachment( AP_DEPTH_STENCIL_ATTACHMENT );
    00289   mFBOAttachments[AP_DEPTH_STENCIL_ATTACHMENT] = attachment;
    00290   attachment->mFBORenderTargets.insert( this );
    00291   attachment->bindAttachment( this, AP_DEPTH_STENCIL_ATTACHMENT );
    00292 }
    00293 //-----------------------------------------------------------------------------
    00294 void FBORenderTarget::removeAttachment( FBOAbstractAttachment* attachment )
    00295 {
    00296   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00297   if( !GLEW_Has_Framebuffer_Object )
    00298     return;
    00299   // collect for all the attachment points
    00300   std::vector<EAttachmentPoint> attachment_points;
    00301   std::map< EAttachmentPoint, ref<FBOAbstractAttachment> >::iterator it = mFBOAttachments.begin();
    00302   for( ; it != mFBOAttachments.end(); ++it )
    00303     if ( it->second == attachment )
    00304       attachment_points.push_back( it->first );
    00305
    00306   // remove it from all the attachment points
    00307   for( unsigned i=0; i<attachment_points.size(); ++i )
    00308     removeAttachment( attachment_points[i] );
    00309 }
    00310 //-----------------------------------------------------------------------------
    00311 void FBORenderTarget::removeAttachment( EAttachmentPoint attach_point )
    00312 {
    00313   VL_CHECK( vl::VisualizationLibrary::isGraphicsInitialized() )
    00314
    00315   VL_CHECK_OGL();
    00316   VL_CHECK(openglContext());
    00317   openglContext()->makeCurrent(); VL_CHECK_OGL();
    00318
    00319   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00320   if( !GLEW_Has_Framebuffer_Object )
    00321     return;
    00322   if ( handle() )
    00323   {
    00324     // save current fbo
    00325     int fbo = -1;
    00326     glGetIntegerv( GL_FRAMEBUFFER_BINDING, &fbo ); VL_CHECK_OGL()
    00327     // bind this fbo
    00328     VL_glBindFramebuffer( GL_FRAMEBUFFER, handle() ); VL_CHECK_OGL()
    00329     // detach should work for any kind of buffer and texture
    00330     VL_glFramebufferRenderbuffer( GL_FRAMEBUFFER, attach_point, GL_RENDERBUFFER, 0 ); VL_CHECK_OGL()
    00331     // restore fbo
    00332     VL_glBindFramebuffer( GL_FRAMEBUFFER, fbo ); VL_CHECK_OGL()
    00333   }
    00334   // remove FBORenderTarget from FBOAbstractAttachment
    00335   FBOAbstractAttachment* fbo_attachment = /* mFBOAttachments.find( attachment ) != mFBOAttachments.end() ? */ mFBOAttachments[attach_point].get() /* : NULL */;
    00336   if ( fbo_attachment )
    00337     fbo_attachment->mFBORenderTargets.erase( this );
    00338   mFBOAttachments.erase( attach_point );
    00339 }
    00340 //-----------------------------------------------------------------------------
    00341 void FBORenderTarget::removeAllAttachments()
    00342 {
    00343   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00344   if( !GLEW_Has_Framebuffer_Object )
    00345     return;
    00346   // look for all the attachment points
    00347   std::vector<EAttachmentPoint> attachment_points;
    00348   std::map< EAttachmentPoint, ref<FBOAbstractAttachment> >::iterator it = mFBOAttachments.begin();
    00349   for( ; it != mFBOAttachments.end(); ++it )
    00350     attachment_points.push_back( it->first );
    00351
    00352   // remove attachment points
    00353   for( unsigned i=0; i<attachment_points.size(); ++i )
    00354     removeAttachment( attachment_points[i] );
    00355 }
    00356 //-----------------------------------------------------------------------------
    00357 void FBOTexture1DAttachment::bindAttachment( FBORenderTarget* fbo, EAttachmentPoint attach_point )
    00358 {
    00359   VL_CHECK_OGL()
    00360   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00361   if( !GLEW_Has_Framebuffer_Object )
    00362     return;
    00363   VL_CHECK( texture() )
    00364   VL_CHECK( texture()->handle() )
    00365   VL_CHECK( texture()->dimension() == GL_TEXTURE_1D )
    00366   VL_CHECK( fbo->width() == texture()->width()  );
    00367
    00368   // binds the FBO for this function call
    00369   ScopedFBOBinding fbo_bind( fbo );
    00370
    00371   VL_glFramebufferTexture1D( GL_FRAMEBUFFER, attach_point, GL_TEXTURE_1D, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
    00372
    00373   // needed to make non-mipmapped textures work with FBO, see framebuffer_object.txt line 442
    00374   glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
    00375   glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
    00376   glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
    00377 }
    00378 //-----------------------------------------------------------------------------
    00379 void FBOTexture2DAttachment::bindAttachment( FBORenderTarget* fbo, EAttachmentPoint attach_point )
    00380 {
    00381   VL_CHECK_OGL()
    00382   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00383   if( !GLEW_Has_Framebuffer_Object )
    00384     return;
    00385   VL_CHECK( texture() )
    00386   VL_CHECK( texture()->handle() )
    00387   // VL_CHECK( texture()->dimension() == GL_TEXTURE_2D )
    00388   VL_CHECK( fbo->width()  <= texture()->width()  );
    00389   VL_CHECK( fbo->height() <= texture()->height() );
    00390
    00391   // binds the FBO for this function call
    00392   ScopedFBOBinding fbo_bind( fbo );
    00393
    00394   int target = texture()->dimension() == TD_TEXTURE_CUBE_MAP ? ( int )textureTarget() : texture()->dimension();
    00395   #ifndef NDEBUG
    00396     if( !( texture()->dimension() == TD_TEXTURE_CUBE_MAP || ( int )textureTarget() == ( int )texture()->dimension() ) )
    00397     {
    00398       Log::bug( "FBOTexture2DAttachment::init(): textureTarget() doens't match texture()->dimension().\n" );
    00399     }
    00400   #endif
    00401
    00402   VL_glFramebufferTexture2D( GL_FRAMEBUFFER, attach_point, target, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
    00403
    00404   // needed to make non-mipmapped textures work with FBO, see framebuffer_object.txt line 442
    00405   if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE )
    00406   {
    00407     glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
    00408     glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
    00409     glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
    00410   }
    00411 }
    00412 //-----------------------------------------------------------------------------
    00413 void FBOTextureAttachment::bindAttachment( FBORenderTarget* fbo, EAttachmentPoint attach_point )
    00414 {
    00415   VL_CHECK_OGL()
    00416   VL_CHECK( GLEW_NV_geometry_shader4||GLEW_EXT_geometry_shader4||GLEW_ARB_geometry_shader4||GLEW_VERSION_3_2 )
    00417   VL_CHECK( texture() )
    00418   VL_CHECK( texture()->handle() )
    00419
    00420   // binds the FBO for this function call
    00421   ScopedFBOBinding fbo_bind( fbo );
    00422
    00423   VL_glFramebufferTexture( GL_FRAMEBUFFER, attach_point, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
    00424
    00425   // needed to make non-mipmapped textures work with FBO, see framebuffer_object.txt line 442
    00426   if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE )
    00427   {
    00428     glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
    00429     glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
    00430     glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
    00431   }
    00432 }
    00433 //-----------------------------------------------------------------------------
    00434 void FBOTexture3DAttachment::bindAttachment( FBORenderTarget* fbo, EAttachmentPoint attach_point )
    00435 {
    00436   VL_CHECK_OGL()
    00437   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00438   if( !GLEW_Has_Framebuffer_Object )
    00439     return;
    00440   VL_CHECK( texture() )
    00441   VL_CHECK( texture()->handle() )
    00442   VL_CHECK( fbo->width()  <= texture()->width()  );
    00443   VL_CHECK( fbo->height() <= texture()->height() );
    00444   VL_CHECK( layer() <= texture()->depth() );
    00445   VL_CHECK( texture()->dimension() == GL_TEXTURE_3D )
    00446
    00447   // binds the FBO for this function call
    00448   ScopedFBOBinding fbo_bind( fbo );
    00449
    00450   VL_glFramebufferTexture3D( GL_FRAMEBUFFER, attach_point, texture()->dimension(), texture()->handle(), mipmapLevel(), layer() ); VL_CHECK_OGL()
    00451
    00452   // needed to make non-mipmapped textures work with FBO, see framebuffer_object.txt line 442
    00453   if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE_ARRAY )
    00454   {
    00455     glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
    00456     glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
    00457     glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
    00458   }
    00459 }
    00460 //-----------------------------------------------------------------------------
    00461 void FBOTextureLayerAttachment::bindAttachment( FBORenderTarget* fbo, EAttachmentPoint attach_point )
    00462 {
    00463   VL_CHECK_OGL()
    00464   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00465   VL_CHECK( GLEW_EXT_texture_array||GLEW_NV_geometry_shader4||GLEW_ARB_geometry_shader4||GLEW_EXT_geometry_shader4||GLEW_VERSION_3_2||GLEW_VERSION_4_0 )
    00466   if( !GLEW_Has_Framebuffer_Object )
    00467     return;
    00468   if( !( GLEW_EXT_texture_array||GLEW_NV_geometry_shader4||GLEW_ARB_geometry_shader4||GLEW_EXT_geometry_shader4||GLEW_VERSION_3_2||GLEW_VERSION_4_0 ) )
    00469     return;
    00470   VL_CHECK( texture() )
    00471   VL_CHECK( texture()->handle() )
    00472   VL_CHECK( texture()->dimension() == GL_TEXTURE_2D_ARRAY || texture()->dimension() == GL_TEXTURE_1D_ARRAY )
    00473   VL_CHECK( fbo->width()  <= texture()->width()  );
    00474   VL_CHECK( fbo->height() <= texture()->height() );
    00475   // VL_CHECK( layer() <= texture()->depth() );
    00476
    00477   // binds the FBO for this function call
    00478   ScopedFBOBinding fbo_bind( fbo );
    00479
    00480   VL_glFramebufferTextureLayer( GL_FRAMEBUFFER, attach_point, texture()->handle(), mipmapLevel(), layer() ); VL_CHECK_OGL()
    00481
    00482   // needed to make non-mipmapped textures work with FBO, see framebuffer_object.txt line 442
    00483   if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE_ARRAY )
    00484   {
    00485     glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
    00486     glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
    00487     glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
    00488   }
    00489 }
    00490 //-----------------------------------------------------------------------------
    00491 void FBOAbstractAttachment::destroy()
    00492 {
    00493   std::set< ref<FBORenderTarget> > fbos = fboRenderTargets();
    00494   for( std::set< ref<FBORenderTarget> >::iterator it = fbos.begin(); it != fbos.end(); ++it )
    00495     it->get()->removeAttachment( this );
    00496 }
    00497 //-----------------------------------------------------------------------------
    00498 void FBORenderbufferAttachment::create()
    00499 {
    00500   VL_CHECK_OGL()
    00501   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00502   if( !GLEW_Has_Framebuffer_Object )
    00503     return;
    00504   if ( !mHandle )
    00505   {
    00506     VL_glGenRenderbuffers( 1, &mHandle ); VL_CHECK_OGL()
    00507     mReallocateRenderbuffer = true;
    00508   }
    00509   VL_CHECK( mHandle )
    00510 }
    00511 //-----------------------------------------------------------------------------
    00512 void FBORenderbufferAttachment::destroy()
    00513 {
    00514   VL_CHECK_OGL()
    00515   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00516   if( !GLEW_Has_Framebuffer_Object )
    00517     return;
    00518   FBOAbstractAttachment::destroy();
    00519   mWidth  = 0;
    00520   mHeight = 0;
    00521   if ( mHandle )
    00522   {
    00523     VL_glDeleteRenderbuffers( 1, &mHandle ); VL_CHECK_OGL()
    00524     mHandle = 0;
    00525     mReallocateRenderbuffer = true;
    00526   }
    00527 }
    00528 //-----------------------------------------------------------------------------
    00529 void FBORenderbufferAttachment::initStorage( int w, int h, int samp )
    00530 {
    00531   VL_CHECK_OGL()
    00532   VL_CHECK( handle() );
    00533   VL_CHECK( w>0 && h>0 );
    00534   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00535   if( !GLEW_Has_Framebuffer_Object )
    00536     return;
    00537
    00538   if ( w != width() || h != height() || samp != samples() || mReallocateRenderbuffer )
    00539   {
    00540     mWidth  = w;
    00541     mHeight = h;
    00542     mSamples = samp;
    00543     VL_glBindRenderbuffer( GL_RENDERBUFFER, handle() ); VL_CHECK_OGL()
    00544     if ( GLEW_Has_Framebuffer_Object_Multisample )
    00545     {
    00546       VL_glRenderbufferStorageMultisample( GL_RENDERBUFFER, samples(), internalType(), width(), height() ); VL_CHECK_OGL()
    00547     }
    00548     else
    00549     {
    00550       VL_CHECK(samples() == 0)
    00551       if (samples())
    00552         Log::error("FBORenderbufferAttachment::initStorage() requesting multisampling storage but current OpenGL implementation does not support it!\n");
    00553       VL_glRenderbufferStorage( GL_RENDERBUFFER, internalType(), width(), height() ); VL_CHECK_OGL()
    00554     }
    00555     VL_glBindRenderbuffer( GL_RENDERBUFFER, 0 ); VL_CHECK_OGL()
    00556     mReallocateRenderbuffer = false;
    00557   }
    00558 }
    00559 //-----------------------------------------------------------------------------
    00560 void FBORenderbufferAttachment::bindAttachment( FBORenderTarget* fbo, EAttachmentPoint attach_point )
    00561 {
    00562   VL_CHECK_OGL()
    00563   VL_CHECK( GLEW_Has_Framebuffer_Object )
    00564   if( !GLEW_Has_Framebuffer_Object )
    00565     return;
    00566
    00567   if (!handle())
    00568     create();
    00569
    00570   // binds the FBO for this function call
    00571   ScopedFBOBinding fbo_bind( fbo );
    00572
    00573   // choose the maximum dimension
    00574   int actual_w = width()  == 0 ? fbo->width()  : width();
    00575   int actual_h = height() == 0 ? fbo->height() : height();
    00576   VL_CHECK( actual_w >= fbo->width() );
    00577   VL_CHECK( actual_h >= fbo->height() );
    00578   initStorage( actual_w, actual_h, samples() );
    00579
    00580   // attach the renderbuffer to the framebuffer's attachment point
    00581   VL_glFramebufferRenderbuffer( GL_FRAMEBUFFER, attach_point, GL_RENDERBUFFER, handle() ); VL_CHECK_OGL()
    00582 }
    00583 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:23.
Permission is granted to use this page to write and publish articles regarding Visualization Library.