Visualization Library 2.0.0

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

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
FramebufferObject.cpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
35 #include <vlCore/Say.hpp>
36 #include <vlCore/Log.hpp>
37 
38 using namespace vl;
39 
40 namespace
41 {
42  class ScopedFBOBinding
43  {
44  GLint mPrevFBO;
45  public:
46  ScopedFBOBinding( FramebufferObject* fbo )
47  {
48  VL_CHECK( fbo );
49  VL_CHECK( fbo->handle() );
50  /*if ( !fbo->handle() )
51  fbo->create();*/
52 
53  // saves current FBO
54  mPrevFBO = 0;
55  glGetIntegerv( GL_FRAMEBUFFER_BINDING, &mPrevFBO ); VL_CHECK_OGL()
56 
57  // binds this FBO
58  VL_glBindFramebuffer( GL_FRAMEBUFFER, fbo->handle() ); VL_CHECK_OGL()
59  }
60 
61  ~ScopedFBOBinding()
62  {
63  // restore the FBO
64  VL_glBindFramebuffer( GL_FRAMEBUFFER, mPrevFBO ); VL_CHECK_OGL()
65  }
66  };
67 }
68 //-----------------------------------------------------------------------------
69 // FramebufferObject
70 //-----------------------------------------------------------------------------
72 {
73  VL_CHECK_OGL();
74  VL_CHECK(openglContext());
75  openglContext()->makeCurrent(); VL_CHECK_OGL();
76 
77  if ( !mHandle )
78  {
79  VL_glGenFramebuffers( 1, ( unsigned int* )&mHandle ); VL_CHECK_OGL();
80  }
81  VL_CHECK( mHandle )
82 }
83 //-----------------------------------------------------------------------------
85 {
86  VL_CHECK_OGL();
87  VL_CHECK(openglContext());
88  openglContext()->makeCurrent(); VL_CHECK_OGL();
89 
90  removeAllAttachments();
91  if ( handle() )
92  {
93  VL_glBindFramebuffer( GL_FRAMEBUFFER, 0 ); VL_CHECK_OGL();
94  VL_glDeleteFramebuffers( 1, &mHandle ); VL_CHECK_OGL();
95  mHandle = 0;
96  }
97  setWidth( 0 );
98  setHeight( 0 );
99 }
100 //-----------------------------------------------------------------------------
102 {
103  VL_CHECK_OGL();
104  VL_CHECK(openglContext());
105  openglContext()->makeCurrent(); VL_CHECK_OGL();
106 
107  if ( !Has_FBO )
108  {
109  Log::error( "FramebufferObject::bindFramebuffer(): framebuffer object not supported.\n" );
110  return;
111  }
112 
113  if ( width() <= 0 || height() <= 0 )
114  {
115  Log::error( Say( "FramebufferObject::bindFramebuffer() called with illegal dimensions: width = %n, height = %n\n" ) << width() << height() );
116  VL_TRAP()
117  }
118 
119  if ( mFBOAttachments.empty() )
120  {
121  Log::error( "FramebufferObject::bindFramebuffer() called with no attachment points!\n" );
122  VL_TRAP()
123  }
124 
125  if ( !handle() )
126  {
127  Log::error( "FramebufferObject::bindFramebuffer() called but handle() == NULL!\n" );
128  VL_TRAP()
129  }
130 
131  VL_glBindFramebuffer( target, handle() ); VL_CHECK_OGL()
132 
133 #if defined(VL_OPENGL)
134  // bind draw buffers
135  if (target == FBB_FRAMEBUFFER || target == FBB_DRAW_FRAMEBUFFER)
136  bindDrawBuffers();
137 
138  // bind read buffer
139  if (target == FBB_FRAMEBUFFER || target == FBB_READ_FRAMEBUFFER)
140  bindReadBuffer();
141 #endif
142 
143  #ifndef NDEBUG
144  GLenum status = VL_glCheckFramebufferStatus( GL_FRAMEBUFFER ); VL_CHECK_OGL()
145  if ( status != GL_FRAMEBUFFER_COMPLETE )
146  {
147  VL_glBindFramebuffer( GL_FRAMEBUFFER, 0 ); VL_CHECK_OGL()
148  }
149  printFramebufferError( status );
150  #endif
151 }
152 //-----------------------------------------------------------------------------
155 {
156  VL_CHECK_OGL();
157  VL_CHECK(openglContext());
158  openglContext()->makeCurrent(); VL_CHECK_OGL();
159 
160  if ( !Has_FBO )
161  {
162  Log::error( "FramebufferObject::checkFramebufferStatus(): framebuffer object not supported.\n" );
163  return 0;
164  }
165 
166  if ( width() <= 0 || height() <= 0 )
167  {
168  Log::error( Say( "FramebufferObject::checkFramebufferStatus() called with illegal dimensions: width = %n, height = %n\n" ) << width() << height() );
169  return 0;
170  }
171 
172  if ( mFBOAttachments.empty() )
173  {
174  Log::error( "FramebufferObject::checkFramebufferStatus() called with no attachment points!\n" );
175  return 0;
176  }
177 
178  if ( !handle() )
179  {
180  Log::error( "FramebufferObject::checkFramebufferStatus() called but handle() == NULL!\n" );
181  return 0;
182  }
183 
184  // binds the FBO for this function call
185  ScopedFBOBinding fbo_bind( this );
186 
187  // checks error
188  GLenum status = VL_glCheckFramebufferStatus( GL_FRAMEBUFFER ); VL_CHECK_OGL()
189 
190  // restore the FBO
191  if ( globalSettings()->verbosityLevel() >= vl::VEL_VERBOSITY_NORMAL )
192  printFramebufferError( status );
193 
194  VL_CHECK( status == GL_FRAMEBUFFER_COMPLETE )
195 
196  return status;
197 }
198 //-----------------------------------------------------------------------------
199 void FramebufferObject::printFramebufferError( GLenum status ) const
200 {
201  switch( status )
202  {
203  case GL_FRAMEBUFFER_COMPLETE:
204  break;
205  case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
206  Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n" ); VL_TRAP()
207  break;
208  case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
209  Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n" ); VL_TRAP()
210  break;
211  case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
212  Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n" ); VL_TRAP()
213  break;
214  case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
215  Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n" ); VL_TRAP()
216  break;
217  case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
218  Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\n" ); VL_TRAP()
219  break;
220  case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
221  Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\n" ); VL_TRAP()
222  break;
223  case GL_FRAMEBUFFER_UNSUPPORTED:
224  Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_UNSUPPORTED\n" ); VL_TRAP()
225  break;
226  case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB:
227  Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB\n" ); VL_TRAP()
228  break;
229  case GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB:
230  Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB\n" ); VL_TRAP()
231  break;
232  case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
233  Log::bug( "FramebufferObject::activate(): GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\n" ); VL_TRAP()
234  break;
235  }
236 }
237 //-----------------------------------------------------------------------------
239 {
240  VL_CHECK( attach_point >= AP_COLOR_ATTACHMENT0 && attach_point <= AP_COLOR_ATTACHMENT15 );
241  VL_CHECK( Has_FBO )
242  if( !Has_FBO )
243  return;
244  removeAttachment( attach_point );
245  mFBOAttachments[attach_point] = attachment;
246  attachment->mFramebufferObjects.insert( this );
247  attachment->bindAttachment( this, attach_point );
248 }
249 //-----------------------------------------------------------------------------
251 {
252  VL_CHECK( attach_point >= AP_COLOR_ATTACHMENT0 && attach_point <= AP_COLOR_ATTACHMENT15 );
253  VL_CHECK( Has_FBO )
254  if( !Has_FBO )
255  return;
256  removeAttachment( attach_point );
257  mFBOAttachments[attach_point] = attachment;
258  attachment->mFramebufferObjects.insert( this );
259  attachment->bindAttachment( this, attach_point );
260 }
261 //-----------------------------------------------------------------------------
263 {
264  VL_CHECK( Has_FBO )
265  if( !Has_FBO )
266  return;
267  removeAttachment( AP_DEPTH_ATTACHMENT );
268  mFBOAttachments[AP_DEPTH_ATTACHMENT] = attachment;
269  attachment->mFramebufferObjects.insert( this );
270  attachment->bindAttachment( this, AP_DEPTH_ATTACHMENT );
271 }
272 //-----------------------------------------------------------------------------
274 {
275  VL_CHECK( Has_FBO )
276  if( !Has_FBO )
277  return;
278  removeAttachment( AP_STENCIL_ATTACHMENT );
279  mFBOAttachments[AP_STENCIL_ATTACHMENT] = attachment;
280  attachment->mFramebufferObjects.insert( this );
281  attachment->bindAttachment( this, AP_STENCIL_ATTACHMENT );
282 }
283 //-----------------------------------------------------------------------------
285 {
286  VL_CHECK( Has_FBO )
287  if( !Has_FBO )
288  return;
289  removeAttachment( AP_DEPTH_STENCIL_ATTACHMENT );
290  mFBOAttachments[AP_DEPTH_STENCIL_ATTACHMENT] = attachment;
291  attachment->mFramebufferObjects.insert( this );
292  attachment->bindAttachment( this, AP_DEPTH_STENCIL_ATTACHMENT );
293 }
294 //-----------------------------------------------------------------------------
296 {
297  VL_CHECK( Has_FBO )
298  if( !Has_FBO )
299  return;
300  // collect for all the attachment points
301  std::vector<EAttachmentPoint> attachment_points;
302  std::map< EAttachmentPoint, ref<FBOAbstractAttachment> >::iterator it = mFBOAttachments.begin();
303  for( ; it != mFBOAttachments.end(); ++it )
304  if ( it->second == attachment )
305  attachment_points.push_back( it->first );
306 
307  // remove it from all the attachment points
308  for( unsigned i=0; i<attachment_points.size(); ++i )
309  removeAttachment( attachment_points[i] );
310 }
311 //-----------------------------------------------------------------------------
313 {
314  VL_CHECK_OGL();
315  VL_CHECK(openglContext());
316  openglContext()->makeCurrent(); VL_CHECK_OGL();
317 
318  VL_CHECK( Has_FBO )
319  if( !Has_FBO )
320  return;
321  if ( handle() )
322  {
323  // save current fbo
324  int fbo = -1;
325  glGetIntegerv( GL_FRAMEBUFFER_BINDING, &fbo ); VL_CHECK_OGL()
326  // bind this fbo
327  VL_glBindFramebuffer( GL_FRAMEBUFFER, handle() ); VL_CHECK_OGL()
328  // detach should work for any kind of buffer and texture
329  VL_glFramebufferRenderbuffer( GL_FRAMEBUFFER, attach_point, GL_RENDERBUFFER, 0 ); VL_CHECK_OGL()
330  // restore fbo
331  VL_glBindFramebuffer( GL_FRAMEBUFFER, fbo ); VL_CHECK_OGL()
332  }
333  // remove FramebufferObject from FBOAbstractAttachment
334  FBOAbstractAttachment* fbo_attachment = /* mFBOAttachments.find( attachment ) != mFBOAttachments.end() ? */ mFBOAttachments[attach_point].get() /* : NULL */;
335  if ( fbo_attachment )
336  fbo_attachment->mFramebufferObjects.erase( this );
337  mFBOAttachments.erase( attach_point );
338 }
339 //-----------------------------------------------------------------------------
341 {
342  VL_CHECK( Has_FBO )
343  if( !Has_FBO )
344  return;
345  // look for all the attachment points
346  std::vector<EAttachmentPoint> attachment_points;
347  std::map< EAttachmentPoint, ref<FBOAbstractAttachment> >::iterator it = mFBOAttachments.begin();
348  for( ; it != mFBOAttachments.end(); ++it )
349  attachment_points.push_back( it->first );
350 
351  // remove attachment points
352  for( unsigned i=0; i<attachment_points.size(); ++i )
353  removeAttachment( attachment_points[i] );
354 }
355 //-----------------------------------------------------------------------------
357 {
358  VL_CHECK_OGL()
359  VL_CHECK( Has_FBO )
360  if( !Has_FBO )
361  return;
362  VL_CHECK( texture() )
363  VL_CHECK( texture()->handle() )
364  VL_CHECK( texture()->dimension() == GL_TEXTURE_1D )
365  VL_CHECK( fbo->width() == texture()->width() );
366 
367  // binds the FBO for this function call
368  ScopedFBOBinding fbo_bind( fbo );
369 
370  VL_glFramebufferTexture1D( GL_FRAMEBUFFER, attach_point, GL_TEXTURE_1D, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
371 
372  // needed to make non-mipmapped textures work with FBO, see framebuffer_object.txt line 442
373  glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
374  glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
375  glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
376 }
377 //-----------------------------------------------------------------------------
379 {
380  VL_CHECK_OGL()
381  VL_CHECK( Has_FBO )
382  if( !Has_FBO )
383  return;
384  VL_CHECK( texture() )
385  VL_CHECK( texture()->handle() )
386  // VL_CHECK( texture()->dimension() == GL_TEXTURE_2D )
387  VL_CHECK( fbo->width() <= texture()->width() );
388  VL_CHECK( fbo->height() <= texture()->height() );
389 
390  // binds the FBO for this function call
391  ScopedFBOBinding fbo_bind( fbo );
392 
393  int target = texture()->dimension() == TD_TEXTURE_CUBE_MAP ? ( int )textureTarget() : texture()->dimension();
394  #ifndef NDEBUG
395  if( !( texture()->dimension() == TD_TEXTURE_CUBE_MAP || ( int )textureTarget() == ( int )texture()->dimension() ) )
396  {
397  Log::bug( "FBOTexture2DAttachment::init(): textureTarget() doens't match texture()->dimension().\n" );
398  }
399  #endif
400 
401  VL_glFramebufferTexture2D( GL_FRAMEBUFFER, attach_point, target, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
402 
403  // needed to make non-mipmapped textures work with FBO, see framebuffer_object.txt line 442
404  if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE )
405  {
406  glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
407  glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
408  glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
409  }
410 }
411 //-----------------------------------------------------------------------------
413 {
414  VL_CHECK_OGL()
415  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 )
416  VL_CHECK( texture() )
417  VL_CHECK( texture()->handle() )
418 
419  // binds the FBO for this function call
420  ScopedFBOBinding fbo_bind( fbo );
421 
422  VL_glFramebufferTexture( GL_FRAMEBUFFER, attach_point, texture()->handle(), mipmapLevel() ); VL_CHECK_OGL()
423 
424  // needed to make non-mipmapped textures work with FBO, see framebuffer_object.txt line 442
425  if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE )
426  {
427  glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
428  glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
429  glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
430  }
431 }
432 //-----------------------------------------------------------------------------
434 {
435  VL_CHECK_OGL()
436  VL_CHECK( Has_FBO )
437  if( !Has_FBO )
438  return;
439  VL_CHECK( texture() )
440  VL_CHECK( texture()->handle() )
441  VL_CHECK( fbo->width() <= texture()->width() );
442  VL_CHECK( fbo->height() <= texture()->height() );
443  VL_CHECK( layer() <= texture()->depth() );
444  VL_CHECK( texture()->dimension() == GL_TEXTURE_3D )
445 
446  // binds the FBO for this function call
447  ScopedFBOBinding fbo_bind( fbo );
448 
449  VL_glFramebufferTexture3D( GL_FRAMEBUFFER, attach_point, texture()->dimension(), texture()->handle(), mipmapLevel(), layer() ); VL_CHECK_OGL()
450 
451  // needed to make non-mipmapped textures work with FBO, see framebuffer_object.txt line 442
452  if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE_ARRAY )
453  {
454  glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
455  glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
456  glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
457  }
458 }
459 //-----------------------------------------------------------------------------
461 {
462  VL_CHECK_OGL()
463  VL_CHECK( Has_FBO )
464  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 )
465  if( !Has_FBO )
466  return;
467  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 ) )
468  return;
469  VL_CHECK( texture() )
470  VL_CHECK( texture()->handle() )
471  VL_CHECK( texture()->dimension() == GL_TEXTURE_2D_ARRAY || texture()->dimension() == GL_TEXTURE_1D_ARRAY )
472  VL_CHECK( fbo->width() <= texture()->width() );
473  VL_CHECK( fbo->height() <= texture()->height() );
474  // VL_CHECK( layer() <= texture()->depth() );
475 
476  // binds the FBO for this function call
477  ScopedFBOBinding fbo_bind( fbo );
478 
479  VL_glFramebufferTextureLayer( GL_FRAMEBUFFER, attach_point, texture()->handle(), mipmapLevel(), layer() ); VL_CHECK_OGL()
480 
481  // needed to make non-mipmapped textures work with FBO, see framebuffer_object.txt line 442
482  if ( texture()->dimension() != TD_TEXTURE_2D_MULTISAMPLE_ARRAY )
483  {
484  glBindTexture( texture()->dimension(), texture()->handle() ); VL_CHECK_OGL()
485  glTexParameteri( texture()->dimension(), GL_TEXTURE_MIN_FILTER, GL_LINEAR ); VL_CHECK_OGL()
486  glBindTexture( texture()->dimension(), 0 ); VL_CHECK_OGL()
487  }
488 }
489 //-----------------------------------------------------------------------------
491 {
492  std::set< ref<FramebufferObject> > fbos = fboFramebuffers();
493  for( std::set< ref<FramebufferObject> >::iterator it = fbos.begin(); it != fbos.end(); ++it )
494  it->get_writable()->removeAttachment( this );
495 }
496 //-----------------------------------------------------------------------------
498 {
499  VL_CHECK_OGL()
500  VL_CHECK( Has_FBO )
501  if( !Has_FBO )
502  return;
503  if ( !mHandle )
504  {
505  VL_glGenRenderbuffers( 1, &mHandle ); VL_CHECK_OGL()
506  mReallocateRenderbuffer = true;
507  }
508  VL_CHECK( mHandle )
509 }
510 //-----------------------------------------------------------------------------
512 {
513  VL_CHECK_OGL()
514  VL_CHECK( Has_FBO )
515  if( !Has_FBO )
516  return;
517 
518  unbindFromAllFBO();
519 
520  mWidth = 0;
521  mHeight = 0;
522  if ( mHandle )
523  {
524  VL_glDeleteRenderbuffers( 1, &mHandle ); VL_CHECK_OGL()
525  mHandle = 0;
526  mReallocateRenderbuffer = true;
527  }
528 }
529 //-----------------------------------------------------------------------------
530 void FBORenderbufferAttachment::initStorage( int w, int h, int samp )
531 {
532  VL_CHECK_OGL()
533  VL_CHECK( handle() );
534  VL_CHECK( w>0 && h>0 );
535  VL_CHECK( Has_FBO )
536  if( !Has_FBO )
537  return;
538 
539  if ( w != width() || h != height() || samp != samples() || mReallocateRenderbuffer )
540  {
541  mWidth = w;
542  mHeight = h;
543  mSamples = samp;
544  VL_glBindRenderbuffer( GL_RENDERBUFFER, handle() ); VL_CHECK_OGL()
545  if ( Has_FBO_Multisample )
546  {
547  VL_glRenderbufferStorageMultisample( GL_RENDERBUFFER, samples(), internalType(), width(), height() ); VL_CHECK_OGL()
548  }
549  else
550  {
551  VL_CHECK(samples() == 0)
552  if (samples())
553  Log::error("FBORenderbufferAttachment::initStorage() requesting multisampling storage but current OpenGL implementation does not support it!\n");
554  VL_glRenderbufferStorage( GL_RENDERBUFFER, internalType(), width(), height() ); VL_CHECK_OGL()
555  }
556  VL_glBindRenderbuffer( GL_RENDERBUFFER, 0 ); VL_CHECK_OGL()
557  mReallocateRenderbuffer = false;
558  }
559 }
560 //-----------------------------------------------------------------------------
562 {
563  VL_CHECK_OGL()
564  VL_CHECK( Has_FBO )
565  if( !Has_FBO )
566  return;
567 
568  if (!handle())
569  createRenderBuffer();
570 
571  // binds the FBO for this function call
572  ScopedFBOBinding fbo_bind( fbo );
573 
574  // choose the maximum dimension
575  int actual_w = width() == 0 ? fbo->width() : width();
576  int actual_h = height() == 0 ? fbo->height() : height();
577  VL_CHECK( actual_w >= fbo->width() );
578  VL_CHECK( actual_h >= fbo->height() );
579  initStorage( actual_w, actual_h, samples() );
580 
581  // attach the renderbuffer to the framebuffer's attachment point
582  VL_glFramebufferRenderbuffer( GL_FRAMEBUFFER, attach_point, GL_RENDERBUFFER, handle() ); VL_CHECK_OGL()
583 }
584 //-----------------------------------------------------------------------------
virtual void bindAttachment(FramebufferObject *fbo, EAttachmentPoint attach_point)
EAttachmentPoint
virtual void bindAttachment(FramebufferObject *fbo, EAttachmentPoint attach_point)=0
A simple String formatting class.
Definition: Say.hpp:124
Abstract class that represents a framebuffer object attachment to be used with FramebufferObject.
virtual void bindAttachment(FramebufferObject *fbo, EAttachmentPoint attach_point)
Base class for all the framebuffer texture attachments (see also FramebufferObject).
int width() const
The width of a render target.
Definition: Framebuffer.hpp:72
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Definition: Log.cpp:165
virtual void bindAttachment(FramebufferObject *fbo, EAttachmentPoint attach_point)
bool Has_GL_Version_4_0
Definition: OpenGL.cpp:60
virtual void bindAttachment(FramebufferObject *fbo, EAttachmentPoint attach_point)
void createRenderBuffer()
Creates a renderbuffer object calling glGenRenderbuffers().
< Outputs normal information messages, plus all error messages.
void deleteRenderBuffer()
Deletes the renderbuffer object created with the createRenderBuffer() method.
virtual void unbindFromAllFBO()
Removes the FBO attachment from all bound FBO render targets.
void addDepthAttachment(FBOAbstractAttachment *attachment)
Binds a depth attachment to a framebuffer object.
Visualization Library main namespace.
void addDepthStencilAttachment(FBOAbstractAttachment *attachment)
Binds a depth-stencil attachment to a framebuffer object.
void addTextureAttachment(EAttachmentPoint attach_point, FBOAbstractTextureAttachment *attachment)
Binds a texture attachment to a framebuffer object.
static void bug(const String &message)
Use this function to provide information about programming errors: wrong parameter initialization...
Definition: Log.cpp:175
#define VL_TRAP()
Definition: checks.hpp:70
void removeAttachment(FBOAbstractAttachment *attachment)
Unbinds the given attachments from a framebuffer object.
void removeAllAttachments()
Unbinds all attachments bound to a framebuffer object.
int height() const
The height of a render target.
Definition: Framebuffer.hpp:75
void addColorAttachment(EAttachmentPoint attach_point, FBOColorBufferAttachment *attachment)
Binds a color attachment to a framebuffer object.
void bindAttachment(FramebufferObject *fbo, EAttachmentPoint attach_point)
bool Has_GL_Version_3_2
Definition: OpenGL.cpp:58
A color renderbuffer to be attached to a FramebufferObject.
void createFBO()
Creates a framebuffer object by calling glGenFramebuffers().
void deleteFBO()
Deletes a framebuffer object by calling glDeleteFramebuffers().
void initStorage()
The same as calling initStorage( width(), height() )
void addStencilAttachment(FBOAbstractAttachment *attachment)
Binds a stencil attachment to a framebuffer object.
void printFramebufferError(GLenum status) const
Prints a human readable description of the error code as returned by glCheckFramebufferStatus() ...
EFramebufferBind
#define VL_CHECK_OGL()
Definition: OpenGL.hpp:156
virtual void bindFramebuffer(EFramebufferBind target=FBB_FRAMEBUFFER)
Makes the framebuffer the current rendering target calling glBindFramebuffer( GL_FRAMEBUFFER, FramebufferObject::handle() ) and initializes all the previously defined attachment points.
Implements a framebuffer object to be used as a rendering target as specified by the ARB_framebuffer_...
GLenum checkFramebufferStatus()
Checks the framebuffer status and returns the value of glCheckFramebufferStatus() ...
virtual void bindAttachment(FramebufferObject *fbo, EAttachmentPoint attach_point)
std::set< ref< FramebufferObject > > mFramebufferObjects
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
bool Has_FBO
Definition: OpenGL.cpp:83
#define VL_CHECK(expr)
Definition: checks.hpp:73
bool Has_FBO_Multisample
Definition: OpenGL.cpp:85
virtual GLuint handle() const
The handle of the framebuffer object as returned by glGenFramebuffers.
VLCORE_EXPORT GlobalSettings * globalSettings()
Returns VisulizationLibrary&#39;s global settings.
Definition: pimpl.cpp:52