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/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
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 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
00135 if (target == FBB_FRAMEBUFFER || target == FBB_DRAW_FRAMEBUFFER)
00136 bindDrawBuffers();
00137
00138
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
00184 ScopedFBOBinding fbo_bind( this );
00185
00186
00187 GLenum status = VL_glCheckFramebufferStatus( GL_FRAMEBUFFER ); VL_CHECK_OGL()
00188
00189
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
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
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
00325 int fbo = -1;
00326 glGetIntegerv( GL_FRAMEBUFFER_BINDING, &fbo ); VL_CHECK_OGL()
00327
00328 VL_glBindFramebuffer( GL_FRAMEBUFFER, handle() ); VL_CHECK_OGL()
00329
00330 VL_glFramebufferRenderbuffer( GL_FRAMEBUFFER, attach_point, GL_RENDERBUFFER, 0 ); VL_CHECK_OGL()
00331
00332 VL_glBindFramebuffer( GL_FRAMEBUFFER, fbo ); VL_CHECK_OGL()
00333 }
00334
00335 FBOAbstractAttachment* fbo_attachment = mFBOAttachments[attach_point].get() ;
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
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
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
00369 ScopedFBOBinding fbo_bind( fbo );
00370
00371 VL_glFramebufferTexture1D( GL_FRAMEBUFFER, attach_point, GL_TEXTURE_1D, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
00372
00373
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
00388 VL_CHECK( fbo->width() <= texture()->width() );
00389 VL_CHECK( fbo->height() <= texture()->height() );
00390
00391
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
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
00421 ScopedFBOBinding fbo_bind( fbo );
00422
00423 VL_glFramebufferTexture( GL_FRAMEBUFFER, attach_point, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
00424
00425
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
00448 ScopedFBOBinding fbo_bind( fbo );
00449
00450 VL_glFramebufferTexture3D( GL_FRAMEBUFFER, attach_point, texture()->dimension(), texture()->handle(), mipmapLevel(), layer() ); VL_CHECK_OGL()
00451
00452
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
00476
00477
00478 ScopedFBOBinding fbo_bind( fbo );
00479
00480 VL_glFramebufferTextureLayer( GL_FRAMEBUFFER, attach_point, texture()->handle(), mipmapLevel(), layer() ); VL_CHECK_OGL()
00481
00482
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
00571 ScopedFBOBinding fbo_bind( fbo );
00572
00573
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
00581 VL_glFramebufferRenderbuffer( GL_FRAMEBUFFER, attach_point, GL_RENDERBUFFER, handle() ); VL_CHECK_OGL()
00582 }
00583