00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <vlCore/VisualizationLibrary.hpp>
00033 #include <vlGraphics/FramebufferObject.hpp>
00034 #include <vlGraphics/OpenGLContext.hpp>
00035 #include <vlCore/GlobalSettings.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( FramebufferObject* fbo )
00048 {
00049 VL_CHECK( fbo );
00050 VL_CHECK( fbo->handle() );
00051
00052
00053
00054
00055 mPrevFBO = 0;
00056 glGetIntegerv( GL_FRAMEBUFFER_BINDING, &mPrevFBO ); VL_CHECK_OGL()
00057
00058
00059 VL_glBindFramebuffer( GL_FRAMEBUFFER, fbo->handle() ); VL_CHECK_OGL()
00060 }
00061
00062 ~ScopedFBOBinding()
00063 {
00064
00065 VL_glBindFramebuffer( GL_FRAMEBUFFER, mPrevFBO ); VL_CHECK_OGL()
00066 }
00067 };
00068 }
00069
00070
00071
00072 void FramebufferObject::createFBO()
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 FramebufferObject::deleteFBO()
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 FramebufferObject::bindFramebuffer( EFramebufferBind target )
00103 {
00104 VL_CHECK_OGL();
00105 VL_CHECK(openglContext());
00106 openglContext()->makeCurrent(); VL_CHECK_OGL();
00107
00108 if ( !Has_FBO )
00109 {
00110 Log::error( "FramebufferObject::bindFramebuffer(): framebuffer object not supported.\n" );
00111 return;
00112 }
00113
00114 if ( width() <= 0 || height() <= 0 )
00115 {
00116 Log::error( Say( "FramebufferObject::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( "FramebufferObject::bindFramebuffer() called with no attachment points!\n" );
00123 VL_TRAP()
00124 }
00125
00126 if ( !handle() )
00127 {
00128 Log::error( "FramebufferObject::bindFramebuffer() called but handle() == NULL!\n" );
00129 VL_TRAP()
00130 }
00131
00132 VL_glBindFramebuffer( target, handle() ); VL_CHECK_OGL()
00133
00134 #if defined(VL_OPENGL)
00135
00136 if (target == FBB_FRAMEBUFFER || target == FBB_DRAW_FRAMEBUFFER)
00137 bindDrawBuffers();
00138
00139
00140 if (target == FBB_FRAMEBUFFER || target == FBB_READ_FRAMEBUFFER)
00141 bindReadBuffer();
00142 #endif
00143
00144 #ifndef NDEBUG
00145 GLenum status = VL_glCheckFramebufferStatus( GL_FRAMEBUFFER ); VL_CHECK_OGL()
00146 if ( status != GL_FRAMEBUFFER_COMPLETE )
00147 {
00148 VL_glBindFramebuffer( GL_FRAMEBUFFER, 0 ); VL_CHECK_OGL()
00149 }
00150 printFramebufferError( status );
00151 #endif
00152 }
00153
00155 GLenum FramebufferObject::checkFramebufferStatus()
00156 {
00157 VL_CHECK_OGL();
00158 VL_CHECK(openglContext());
00159 openglContext()->makeCurrent(); VL_CHECK_OGL();
00160
00161 if ( !Has_FBO )
00162 {
00163 Log::error( "FramebufferObject::checkFramebufferStatus(): framebuffer object not supported.\n" );
00164 return 0;
00165 }
00166
00167 if ( width() <= 0 || height() <= 0 )
00168 {
00169 Log::error( Say( "FramebufferObject::checkFramebufferStatus() called with illegal dimensions: width = %n, height = %n\n" ) << width() << height() );
00170 return 0;
00171 }
00172
00173 if ( mFBOAttachments.empty() )
00174 {
00175 Log::error( "FramebufferObject::checkFramebufferStatus() called with no attachment points!\n" );
00176 return 0;
00177 }
00178
00179 if ( !handle() )
00180 {
00181 Log::error( "FramebufferObject::checkFramebufferStatus() called but handle() == NULL!\n" );
00182 return 0;
00183 }
00184
00185
00186 ScopedFBOBinding fbo_bind( this );
00187
00188
00189 GLenum status = VL_glCheckFramebufferStatus( GL_FRAMEBUFFER ); VL_CHECK_OGL()
00190
00191
00192 if ( globalSettings()->verbosityLevel() >= vl::VEL_VERBOSITY_NORMAL )
00193 printFramebufferError( status );
00194
00195 VL_CHECK( status == GL_FRAMEBUFFER_COMPLETE )
00196
00197 return status;
00198 }
00199
00200 void FramebufferObject::printFramebufferError( GLenum status ) const
00201 {
00202 switch( status )
00203 {
00204 case GL_FRAMEBUFFER_COMPLETE:
00205 break;
00206 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
00207 Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n" ); VL_TRAP()
00208 break;
00209 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
00210 Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n" ); VL_TRAP()
00211 break;
00212 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
00213 Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n" ); VL_TRAP()
00214 break;
00215 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
00216 Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n" ); VL_TRAP()
00217 break;
00218 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
00219 Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\n" ); VL_TRAP()
00220 break;
00221 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
00222 Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\n" ); VL_TRAP()
00223 break;
00224 case GL_FRAMEBUFFER_UNSUPPORTED:
00225 Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_UNSUPPORTED\n" ); VL_TRAP()
00226 break;
00227 case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB:
00228 Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB\n" ); VL_TRAP()
00229 break;
00230 case GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB:
00231 Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB\n" ); VL_TRAP()
00232 break;
00233 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
00234 Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\n" ); VL_TRAP()
00235 break;
00236 }
00237 }
00238
00239 void FramebufferObject::addColorAttachment( EAttachmentPoint attach_point, FBOColorBufferAttachment* attachment )
00240 {
00241 VL_CHECK( attach_point >= AP_COLOR_ATTACHMENT0 && attach_point <= AP_COLOR_ATTACHMENT15 );
00242 VL_CHECK( Has_FBO )
00243 if( !Has_FBO )
00244 return;
00245 removeAttachment( attach_point );
00246 mFBOAttachments[attach_point] = attachment;
00247 attachment->mFramebufferObjects.insert( this );
00248 attachment->bindAttachment( this, attach_point );
00249 }
00250
00251 void FramebufferObject::addTextureAttachment( EAttachmentPoint attach_point, FBOAbstractTextureAttachment* attachment )
00252 {
00253 VL_CHECK( attach_point >= AP_COLOR_ATTACHMENT0 && attach_point <= AP_COLOR_ATTACHMENT15 ||
00254 attach_point == AP_DEPTH_ATTACHMENT ||
00255 attach_point == AP_STENCIL_ATTACHMENT ||
00256 attach_point == AP_DEPTH_STENCIL_ATTACHMENT);
00257 VL_CHECK( Has_FBO )
00258 if( !Has_FBO )
00259 return;
00260 removeAttachment( attach_point );
00261 mFBOAttachments[attach_point] = attachment;
00262 attachment->mFramebufferObjects.insert( this );
00263 attachment->bindAttachment( this, attach_point );
00264 }
00265
00266 void FramebufferObject::addDepthAttachment( FBOAbstractAttachment* attachment )
00267 {
00268 VL_CHECK( Has_FBO )
00269 if( !Has_FBO )
00270 return;
00271 removeAttachment( AP_DEPTH_ATTACHMENT );
00272 mFBOAttachments[AP_DEPTH_ATTACHMENT] = attachment;
00273 attachment->mFramebufferObjects.insert( this );
00274 attachment->bindAttachment( this, AP_DEPTH_ATTACHMENT );
00275 }
00276
00277 void FramebufferObject::addStencilAttachment( FBOAbstractAttachment* attachment )
00278 {
00279 VL_CHECK( Has_FBO )
00280 if( !Has_FBO )
00281 return;
00282 removeAttachment( AP_STENCIL_ATTACHMENT );
00283 mFBOAttachments[AP_STENCIL_ATTACHMENT] = attachment;
00284 attachment->mFramebufferObjects.insert( this );
00285 attachment->bindAttachment( this, AP_STENCIL_ATTACHMENT );
00286 }
00287
00288 void FramebufferObject::addDepthStencilAttachment( FBOAbstractAttachment* attachment )
00289 {
00290 VL_CHECK( Has_FBO )
00291 if( !Has_FBO )
00292 return;
00293 removeAttachment( AP_DEPTH_STENCIL_ATTACHMENT );
00294 mFBOAttachments[AP_DEPTH_STENCIL_ATTACHMENT] = attachment;
00295 attachment->mFramebufferObjects.insert( this );
00296 attachment->bindAttachment( this, AP_DEPTH_STENCIL_ATTACHMENT );
00297 }
00298
00299 void FramebufferObject::removeAttachment( FBOAbstractAttachment* attachment )
00300 {
00301 VL_CHECK( Has_FBO )
00302 if( !Has_FBO )
00303 return;
00304
00305 std::vector<EAttachmentPoint> attachment_points;
00306 std::map< EAttachmentPoint, ref<FBOAbstractAttachment> >::iterator it = mFBOAttachments.begin();
00307 for( ; it != mFBOAttachments.end(); ++it )
00308 if ( it->second == attachment )
00309 attachment_points.push_back( it->first );
00310
00311
00312 for( unsigned i=0; i<attachment_points.size(); ++i )
00313 removeAttachment( attachment_points[i] );
00314 }
00315
00316 void FramebufferObject::removeAttachment( EAttachmentPoint attach_point )
00317 {
00318 VL_CHECK( vl::VisualizationLibrary::isGraphicsInitialized() )
00319
00320 VL_CHECK_OGL();
00321 VL_CHECK(openglContext());
00322 openglContext()->makeCurrent(); VL_CHECK_OGL();
00323
00324 VL_CHECK( Has_FBO )
00325 if( !Has_FBO )
00326 return;
00327 if ( handle() )
00328 {
00329
00330 int fbo = -1;
00331 glGetIntegerv( GL_FRAMEBUFFER_BINDING, &fbo ); VL_CHECK_OGL()
00332
00333 VL_glBindFramebuffer( GL_FRAMEBUFFER, handle() ); VL_CHECK_OGL()
00334
00335 VL_glFramebufferRenderbuffer( GL_FRAMEBUFFER, attach_point, GL_RENDERBUFFER, 0 ); VL_CHECK_OGL()
00336
00337 VL_glBindFramebuffer( GL_FRAMEBUFFER, fbo ); VL_CHECK_OGL()
00338 }
00339
00340 FBOAbstractAttachment* fbo_attachment = mFBOAttachments[attach_point].get() ;
00341 if ( fbo_attachment )
00342 fbo_attachment->mFramebufferObjects.erase( this );
00343 mFBOAttachments.erase( attach_point );
00344 }
00345
00346 void FramebufferObject::removeAllAttachments()
00347 {
00348 VL_CHECK( Has_FBO )
00349 if( !Has_FBO )
00350 return;
00351
00352 std::vector<EAttachmentPoint> attachment_points;
00353 std::map< EAttachmentPoint, ref<FBOAbstractAttachment> >::iterator it = mFBOAttachments.begin();
00354 for( ; it != mFBOAttachments.end(); ++it )
00355 attachment_points.push_back( it->first );
00356
00357
00358 for( unsigned i=0; i<attachment_points.size(); ++i )
00359 removeAttachment( attachment_points[i] );
00360 }
00361
00362 void FBOTexture1DAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00363 {
00364 VL_CHECK_OGL()
00365 VL_CHECK( Has_FBO )
00366 if( !Has_FBO )
00367 return;
00368 VL_CHECK( texture() )
00369 VL_CHECK( texture()->handle() )
00370 VL_CHECK( texture()->dimension() == GL_TEXTURE_1D )
00371 VL_CHECK( fbo->width() == texture()->width() );
00372
00373
00374 ScopedFBOBinding fbo_bind( fbo );
00375
00376 VL_glFramebufferTexture1D( GL_FRAMEBUFFER, attach_point, GL_TEXTURE_1D, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
00377
00378
00379 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00380 glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
00381 glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
00382 }
00383
00384 void FBOTexture2DAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00385 {
00386 VL_CHECK_OGL()
00387 VL_CHECK( Has_FBO )
00388 if( !Has_FBO )
00389 return;
00390 VL_CHECK( texture() )
00391 VL_CHECK( texture()->handle() )
00392
00393 VL_CHECK( fbo->width() <= texture()->width() );
00394 VL_CHECK( fbo->height() <= texture()->height() );
00395
00396
00397 ScopedFBOBinding fbo_bind( fbo );
00398
00399 int target = texture()->dimension() == TD_TEXTURE_CUBE_MAP ? ( int )textureTarget() : texture()->dimension();
00400 #ifndef NDEBUG
00401 if( !( texture()->dimension() == TD_TEXTURE_CUBE_MAP || ( int )textureTarget() == ( int )texture()->dimension() ) )
00402 {
00403 Log::bug( "FBOTexture2DAttachment::init(): textureTarget() doens't match texture()->dimension().\n" );
00404 }
00405 #endif
00406
00407 VL_glFramebufferTexture2D( GL_FRAMEBUFFER, attach_point, target, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
00408
00409
00410 if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE )
00411 {
00412 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00413 glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
00414 glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
00415 }
00416 }
00417
00418 void FBOTextureAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00419 {
00420 VL_CHECK_OGL()
00421 VL_CHECK( Has_GL_NV_geometry_shader4||Has_GL_EXT_geometry_shader4||Has_GL_ARB_geometry_shader4||Has_GL_Version_3_2||Has_GL_Version_4_0 )
00422 VL_CHECK( texture() )
00423 VL_CHECK( texture()->handle() )
00424
00425
00426 ScopedFBOBinding fbo_bind( fbo );
00427
00428 VL_glFramebufferTexture( GL_FRAMEBUFFER, attach_point, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
00429
00430
00431 if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE )
00432 {
00433 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00434 glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
00435 glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
00436 }
00437 }
00438
00439 void FBOTexture3DAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00440 {
00441 VL_CHECK_OGL()
00442 VL_CHECK( Has_FBO )
00443 if( !Has_FBO )
00444 return;
00445 VL_CHECK( texture() )
00446 VL_CHECK( texture()->handle() )
00447 VL_CHECK( fbo->width() <= texture()->width() );
00448 VL_CHECK( fbo->height() <= texture()->height() );
00449 VL_CHECK( layer() <= texture()->depth() );
00450 VL_CHECK( texture()->dimension() == GL_TEXTURE_3D )
00451
00452
00453 ScopedFBOBinding fbo_bind( fbo );
00454
00455 VL_glFramebufferTexture3D( GL_FRAMEBUFFER, attach_point, texture()->dimension(), texture()->handle(), mipmapLevel(), layer() ); VL_CHECK_OGL()
00456
00457
00458 if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE_ARRAY )
00459 {
00460 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00461 glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
00462 glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
00463 }
00464 }
00465
00466 void FBOTextureLayerAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00467 {
00468 VL_CHECK_OGL()
00469 VL_CHECK( Has_FBO )
00470 VL_CHECK( Has_GL_EXT_texture_array||Has_GL_NV_geometry_shader4||Has_GL_ARB_geometry_shader4||Has_GL_EXT_geometry_shader4||Has_GL_Version_3_2||Has_GL_Version_4_0 )
00471 if( !Has_FBO )
00472 return;
00473 if( !( Has_GL_EXT_texture_array||Has_GL_NV_geometry_shader4||Has_GL_ARB_geometry_shader4||Has_GL_EXT_geometry_shader4||Has_GL_Version_3_2||Has_GL_Version_4_0 ) )
00474 return;
00475 VL_CHECK( texture() )
00476 VL_CHECK( texture()->handle() )
00477 VL_CHECK( texture()->dimension() == GL_TEXTURE_2D_ARRAY || texture()->dimension() == GL_TEXTURE_1D_ARRAY )
00478 VL_CHECK( fbo->width() <= texture()->width() );
00479 VL_CHECK( fbo->height() <= texture()->height() );
00480
00481
00482
00483 ScopedFBOBinding fbo_bind( fbo );
00484
00485 VL_glFramebufferTextureLayer( GL_FRAMEBUFFER, attach_point, texture()->handle(), mipmapLevel(), layer() ); VL_CHECK_OGL()
00486
00487
00488 if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE_ARRAY )
00489 {
00490 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00491 glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
00492 glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
00493 }
00494 }
00495
00496 void FBOAbstractAttachment::unbindFromAllFBO()
00497 {
00498 std::set< ref<FramebufferObject> > fbos = fboFramebuffers();
00499 for( std::set< ref<FramebufferObject> >::iterator it = fbos.begin(); it != fbos.end(); ++it )
00500 it->get_writable()->removeAttachment( this );
00501 }
00502
00503 void FBORenderbufferAttachment::createRenderBuffer()
00504 {
00505 VL_CHECK_OGL()
00506 VL_CHECK( Has_FBO )
00507 if( !Has_FBO )
00508 return;
00509 if ( !mHandle )
00510 {
00511 VL_glGenRenderbuffers( 1, &mHandle ); VL_CHECK_OGL()
00512 mReallocateRenderbuffer = true;
00513 }
00514 VL_CHECK( mHandle )
00515 }
00516
00517 void FBORenderbufferAttachment::deleteRenderBuffer()
00518 {
00519 VL_CHECK_OGL()
00520 VL_CHECK( Has_FBO )
00521 if( !Has_FBO )
00522 return;
00523
00524 unbindFromAllFBO();
00525
00526 mWidth = 0;
00527 mHeight = 0;
00528 if ( mHandle )
00529 {
00530 VL_glDeleteRenderbuffers( 1, &mHandle ); VL_CHECK_OGL()
00531 mHandle = 0;
00532 mReallocateRenderbuffer = true;
00533 }
00534 }
00535
00536 void FBORenderbufferAttachment::initStorage( int w, int h, int samp )
00537 {
00538 VL_CHECK_OGL()
00539 VL_CHECK( handle() );
00540 VL_CHECK( w>0 && h>0 );
00541 VL_CHECK( Has_FBO )
00542 if( !Has_FBO )
00543 return;
00544
00545 if ( w != width() || h != height() || samp != samples() || mReallocateRenderbuffer )
00546 {
00547 mWidth = w;
00548 mHeight = h;
00549 mSamples = samp;
00550 VL_glBindRenderbuffer( GL_RENDERBUFFER, handle() ); VL_CHECK_OGL()
00551 if ( Has_FBO_Multisample && samples() != 0)
00552 {
00553 VL_glRenderbufferStorageMultisample( GL_RENDERBUFFER, samples(), internalType(), width(), height() ); VL_CHECK_OGL()
00554 }
00555 else
00556 {
00557 VL_CHECK(samples() == 0)
00558 if (samples())
00559 Log::error("FBORenderbufferAttachment::initStorage() requesting multisampling storage but current OpenGL implementation does not support it!\n");
00560 VL_glRenderbufferStorage( GL_RENDERBUFFER, internalType(), width(), height() ); VL_CHECK_OGL()
00561 }
00562 VL_glBindRenderbuffer( GL_RENDERBUFFER, 0 ); VL_CHECK_OGL()
00563 mReallocateRenderbuffer = false;
00564 }
00565 }
00566
00567 void FBORenderbufferAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00568 {
00569 VL_CHECK_OGL()
00570 VL_CHECK( Has_FBO )
00571 if( !Has_FBO )
00572 return;
00573
00574 if (!handle())
00575 createRenderBuffer();
00576
00577
00578 ScopedFBOBinding fbo_bind( fbo );
00579
00580
00581 int actual_w = width() == 0 ? fbo->width() : width();
00582 int actual_h = height() == 0 ? fbo->height() : height();
00583 VL_CHECK( actual_w >= fbo->width() );
00584 VL_CHECK( actual_h >= fbo->height() );
00585 initStorage( actual_w, actual_h, samples() );
00586
00587
00588 VL_glFramebufferRenderbuffer( GL_FRAMEBUFFER, attach_point, GL_RENDERBUFFER, handle() ); VL_CHECK_OGL()
00589 }
00590