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 VL_CHECK( Has_FBO )
00255 if( !Has_FBO )
00256 return;
00257 removeAttachment( attach_point );
00258 mFBOAttachments[attach_point] = attachment;
00259 attachment->mFramebufferObjects.insert( this );
00260 attachment->bindAttachment( this, attach_point );
00261 }
00262
00263 void FramebufferObject::addDepthAttachment( FBOAbstractAttachment* attachment )
00264 {
00265 VL_CHECK( Has_FBO )
00266 if( !Has_FBO )
00267 return;
00268 removeAttachment( AP_DEPTH_ATTACHMENT );
00269 mFBOAttachments[AP_DEPTH_ATTACHMENT] = attachment;
00270 attachment->mFramebufferObjects.insert( this );
00271 attachment->bindAttachment( this, AP_DEPTH_ATTACHMENT );
00272 }
00273
00274 void FramebufferObject::addStencilAttachment( FBOAbstractAttachment* attachment )
00275 {
00276 VL_CHECK( Has_FBO )
00277 if( !Has_FBO )
00278 return;
00279 removeAttachment( AP_STENCIL_ATTACHMENT );
00280 mFBOAttachments[AP_STENCIL_ATTACHMENT] = attachment;
00281 attachment->mFramebufferObjects.insert( this );
00282 attachment->bindAttachment( this, AP_STENCIL_ATTACHMENT );
00283 }
00284
00285 void FramebufferObject::addDepthStencilAttachment( FBOAbstractAttachment* attachment )
00286 {
00287 VL_CHECK( Has_FBO )
00288 if( !Has_FBO )
00289 return;
00290 removeAttachment( AP_DEPTH_STENCIL_ATTACHMENT );
00291 mFBOAttachments[AP_DEPTH_STENCIL_ATTACHMENT] = attachment;
00292 attachment->mFramebufferObjects.insert( this );
00293 attachment->bindAttachment( this, AP_DEPTH_STENCIL_ATTACHMENT );
00294 }
00295
00296 void FramebufferObject::removeAttachment( FBOAbstractAttachment* attachment )
00297 {
00298 VL_CHECK( Has_FBO )
00299 if( !Has_FBO )
00300 return;
00301
00302 std::vector<EAttachmentPoint> attachment_points;
00303 std::map< EAttachmentPoint, ref<FBOAbstractAttachment> >::iterator it = mFBOAttachments.begin();
00304 for( ; it != mFBOAttachments.end(); ++it )
00305 if ( it->second == attachment )
00306 attachment_points.push_back( it->first );
00307
00308
00309 for( unsigned i=0; i<attachment_points.size(); ++i )
00310 removeAttachment( attachment_points[i] );
00311 }
00312
00313 void FramebufferObject::removeAttachment( EAttachmentPoint attach_point )
00314 {
00315 VL_CHECK( vl::VisualizationLibrary::isGraphicsInitialized() )
00316
00317 VL_CHECK_OGL();
00318 VL_CHECK(openglContext());
00319 openglContext()->makeCurrent(); VL_CHECK_OGL();
00320
00321 VL_CHECK( Has_FBO )
00322 if( !Has_FBO )
00323 return;
00324 if ( handle() )
00325 {
00326
00327 int fbo = -1;
00328 glGetIntegerv( GL_FRAMEBUFFER_BINDING, &fbo ); VL_CHECK_OGL()
00329
00330 VL_glBindFramebuffer( GL_FRAMEBUFFER, handle() ); VL_CHECK_OGL()
00331
00332 VL_glFramebufferRenderbuffer( GL_FRAMEBUFFER, attach_point, GL_RENDERBUFFER, 0 ); VL_CHECK_OGL()
00333
00334 VL_glBindFramebuffer( GL_FRAMEBUFFER, fbo ); VL_CHECK_OGL()
00335 }
00336
00337 FBOAbstractAttachment* fbo_attachment = mFBOAttachments[attach_point].get() ;
00338 if ( fbo_attachment )
00339 fbo_attachment->mFramebufferObjects.erase( this );
00340 mFBOAttachments.erase( attach_point );
00341 }
00342
00343 void FramebufferObject::removeAllAttachments()
00344 {
00345 VL_CHECK( Has_FBO )
00346 if( !Has_FBO )
00347 return;
00348
00349 std::vector<EAttachmentPoint> attachment_points;
00350 std::map< EAttachmentPoint, ref<FBOAbstractAttachment> >::iterator it = mFBOAttachments.begin();
00351 for( ; it != mFBOAttachments.end(); ++it )
00352 attachment_points.push_back( it->first );
00353
00354
00355 for( unsigned i=0; i<attachment_points.size(); ++i )
00356 removeAttachment( attachment_points[i] );
00357 }
00358
00359 void FBOTexture1DAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00360 {
00361 VL_CHECK_OGL()
00362 VL_CHECK( Has_FBO )
00363 if( !Has_FBO )
00364 return;
00365 VL_CHECK( texture() )
00366 VL_CHECK( texture()->handle() )
00367 VL_CHECK( texture()->dimension() == GL_TEXTURE_1D )
00368 VL_CHECK( fbo->width() == texture()->width() );
00369
00370
00371 ScopedFBOBinding fbo_bind( fbo );
00372
00373 VL_glFramebufferTexture1D( GL_FRAMEBUFFER, attach_point, GL_TEXTURE_1D, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
00374
00375
00376 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00377 glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
00378 glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
00379 }
00380
00381 void FBOTexture2DAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00382 {
00383 VL_CHECK_OGL()
00384 VL_CHECK( Has_FBO )
00385 if( !Has_FBO )
00386 return;
00387 VL_CHECK( texture() )
00388 VL_CHECK( texture()->handle() )
00389
00390 VL_CHECK( fbo->width() <= texture()->width() );
00391 VL_CHECK( fbo->height() <= texture()->height() );
00392
00393
00394 ScopedFBOBinding fbo_bind( fbo );
00395
00396 int target = texture()->dimension() == TD_TEXTURE_CUBE_MAP ? ( int )textureTarget() : texture()->dimension();
00397 #ifndef NDEBUG
00398 if( !( texture()->dimension() == TD_TEXTURE_CUBE_MAP || ( int )textureTarget() == ( int )texture()->dimension() ) )
00399 {
00400 Log::bug( "FBOTexture2DAttachment::init(): textureTarget() doens't match texture()->dimension().\n" );
00401 }
00402 #endif
00403
00404 VL_glFramebufferTexture2D( GL_FRAMEBUFFER, attach_point, target, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
00405
00406
00407 if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE )
00408 {
00409 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00410 glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
00411 glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
00412 }
00413 }
00414
00415 void FBOTextureAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00416 {
00417 VL_CHECK_OGL()
00418 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 )
00419 VL_CHECK( texture() )
00420 VL_CHECK( texture()->handle() )
00421
00422
00423 ScopedFBOBinding fbo_bind( fbo );
00424
00425 VL_glFramebufferTexture( GL_FRAMEBUFFER, attach_point, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
00426
00427
00428 if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE )
00429 {
00430 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00431 glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
00432 glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
00433 }
00434 }
00435
00436 void FBOTexture3DAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00437 {
00438 VL_CHECK_OGL()
00439 VL_CHECK( Has_FBO )
00440 if( !Has_FBO )
00441 return;
00442 VL_CHECK( texture() )
00443 VL_CHECK( texture()->handle() )
00444 VL_CHECK( fbo->width() <= texture()->width() );
00445 VL_CHECK( fbo->height() <= texture()->height() );
00446 VL_CHECK( layer() <= texture()->depth() );
00447 VL_CHECK( texture()->dimension() == GL_TEXTURE_3D )
00448
00449
00450 ScopedFBOBinding fbo_bind( fbo );
00451
00452 VL_glFramebufferTexture3D( GL_FRAMEBUFFER, attach_point, texture()->dimension(), texture()->handle(), mipmapLevel(), layer() ); VL_CHECK_OGL()
00453
00454
00455 if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE_ARRAY )
00456 {
00457 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00458 glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
00459 glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
00460 }
00461 }
00462
00463 void FBOTextureLayerAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00464 {
00465 VL_CHECK_OGL()
00466 VL_CHECK( Has_FBO )
00467 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 )
00468 if( !Has_FBO )
00469 return;
00470 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 ) )
00471 return;
00472 VL_CHECK( texture() )
00473 VL_CHECK( texture()->handle() )
00474 VL_CHECK( texture()->dimension() == GL_TEXTURE_2D_ARRAY || texture()->dimension() == GL_TEXTURE_1D_ARRAY )
00475 VL_CHECK( fbo->width() <= texture()->width() );
00476 VL_CHECK( fbo->height() <= texture()->height() );
00477
00478
00479
00480 ScopedFBOBinding fbo_bind( fbo );
00481
00482 VL_glFramebufferTextureLayer( GL_FRAMEBUFFER, attach_point, texture()->handle(), mipmapLevel(), layer() ); VL_CHECK_OGL()
00483
00484
00485 if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE_ARRAY )
00486 {
00487 glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
00488 glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
00489 glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
00490 }
00491 }
00492
00493 void FBOAbstractAttachment::unbindFromAllFBO()
00494 {
00495 std::set< ref<FramebufferObject> > fbos = fboFramebuffers();
00496 for( std::set< ref<FramebufferObject> >::iterator it = fbos.begin(); it != fbos.end(); ++it )
00497 it->get_writable()->removeAttachment( this );
00498 }
00499
00500 void FBORenderbufferAttachment::createRenderBuffer()
00501 {
00502 VL_CHECK_OGL()
00503 VL_CHECK( Has_FBO )
00504 if( !Has_FBO )
00505 return;
00506 if ( !mHandle )
00507 {
00508 VL_glGenRenderbuffers( 1, &mHandle ); VL_CHECK_OGL()
00509 mReallocateRenderbuffer = true;
00510 }
00511 VL_CHECK( mHandle )
00512 }
00513
00514 void FBORenderbufferAttachment::deleteRenderBuffer()
00515 {
00516 VL_CHECK_OGL()
00517 VL_CHECK( Has_FBO )
00518 if( !Has_FBO )
00519 return;
00520
00521 unbindFromAllFBO();
00522
00523 mWidth = 0;
00524 mHeight = 0;
00525 if ( mHandle )
00526 {
00527 VL_glDeleteRenderbuffers( 1, &mHandle ); VL_CHECK_OGL()
00528 mHandle = 0;
00529 mReallocateRenderbuffer = true;
00530 }
00531 }
00532
00533 void FBORenderbufferAttachment::initStorage( int w, int h, int samp )
00534 {
00535 VL_CHECK_OGL()
00536 VL_CHECK( handle() );
00537 VL_CHECK( w>0 && h>0 );
00538 VL_CHECK( Has_FBO )
00539 if( !Has_FBO )
00540 return;
00541
00542 if ( w != width() || h != height() || samp != samples() || mReallocateRenderbuffer )
00543 {
00544 mWidth = w;
00545 mHeight = h;
00546 mSamples = samp;
00547 VL_glBindRenderbuffer( GL_RENDERBUFFER, handle() ); VL_CHECK_OGL()
00548 if ( Has_FBO_Multisample )
00549 {
00550 VL_glRenderbufferStorageMultisample( GL_RENDERBUFFER, samples(), internalType(), width(), height() ); VL_CHECK_OGL()
00551 }
00552 else
00553 {
00554 VL_CHECK(samples() == 0)
00555 if (samples())
00556 Log::error("FBORenderbufferAttachment::initStorage() requesting multisampling storage but current OpenGL implementation does not support it!\n");
00557 VL_glRenderbufferStorage( GL_RENDERBUFFER, internalType(), width(), height() ); VL_CHECK_OGL()
00558 }
00559 VL_glBindRenderbuffer( GL_RENDERBUFFER, 0 ); VL_CHECK_OGL()
00560 mReallocateRenderbuffer = false;
00561 }
00562 }
00563
00564 void FBORenderbufferAttachment::bindAttachment( FramebufferObject* fbo, EAttachmentPoint attach_point )
00565 {
00566 VL_CHECK_OGL()
00567 VL_CHECK( Has_FBO )
00568 if( !Has_FBO )
00569 return;
00570
00571 if (!handle())
00572 createRenderBuffer();
00573
00574
00575 ScopedFBOBinding fbo_bind( fbo );
00576
00577
00578 int actual_w = width() == 0 ? fbo->width() : width();
00579 int actual_h = height() == 0 ? fbo->height() : height();
00580 VL_CHECK( actual_w >= fbo->width() );
00581 VL_CHECK( actual_h >= fbo->height() );
00582 initStorage( actual_w, actual_h, samples() );
00583
00584
00585 VL_glFramebufferRenderbuffer( GL_FRAMEBUFFER, attach_point, GL_RENDERBUFFER, handle() ); VL_CHECK_OGL()
00586 }
00587