OSG  3.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FrameBufferObject.h
Go to the documentation of this file.
1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version. The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * OpenSceneGraph Public License for more details.
12 */
13 
14 // initial FBO support written by Marco Jez, June 2005.
15 
16 #ifndef OSG_FRAMEBUFFEROBJECT
17 #define OSG_FRAMEBUFFEROBJECT 1
18 
19 #include <osg/GL>
20 #include <osg/Texture>
21 #include <osg/buffered_value>
22 #include <osg/Camera>
23 
24 #ifndef GL_EXT_framebuffer_object
25 #define GL_EXT_framebuffer_object 1
26 #define GL_FRAMEBUFFER_EXT 0x8D40
27 #define GL_RENDERBUFFER_EXT 0x8D41
28 // #define GL_STENCIL_INDEX_EXT 0x8D45 // removed in rev. #114 of the spec
29 #define GL_STENCIL_INDEX1_EXT 0x8D46
30 #define GL_STENCIL_INDEX4_EXT 0x8D47
31 #define GL_STENCIL_INDEX8_EXT 0x8D48
32 #define GL_STENCIL_INDEX16_EXT 0x8D49
33 #define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
34 #define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
35 #define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
36 #define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
37 #define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
38 #define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
39 #define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
40 #define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
41 #define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
42 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
43 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
44 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
45 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
46 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
47 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
48 #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
49 #define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
50 #define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
51 #define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
52 #define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
53 #define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
54 #define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
55 #define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
56 #define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
57 #define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
58 #define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
59 #define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
60 #define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
61 #define GL_COLOR_ATTACHMENT13_EXT 0x8CED
62 #define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
63 #define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
64 #define GL_DEPTH_ATTACHMENT_EXT 0x8D00
65 #define GL_STENCIL_ATTACHMENT_EXT 0x8D20
66 #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
67 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
68 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
69 #define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8
70 #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
71 #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
72 #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
73 #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
74 #define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
75 #define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
76 #define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
77 #define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
78 #define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
79 #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
80 #endif
81 
82 #ifndef GL_EXT_framebuffer_blit
83 #define GL_EXT_framebuffer_blit 1
84 #define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6
85 #define GL_READ_FRAMEBUFFER_EXT 0x8CA8
86 #define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
87 #define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
88 #endif
89 
90 #ifndef GL_EXT_framebuffer_multisample
91 #define GL_EXT_framebuffer_multisample 1
92 #define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
93 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
94 #define GL_MAX_SAMPLES_EXT 0x8D57
95 #endif
96 
97 #ifndef GL_MAX_SAMPLES_EXT
98 // Workaround for Centos 5 and other distros that define
99 // GL_EXT_framebuffer_multisample but not GL_MAX_SAMPLES_EXT
100 #define GL_MAX_SAMPLES_EXT 0x8D57
101 #endif
102 
103 #ifndef GL_NV_framebuffer_multisample_coverage
104 #define GL_NV_framebuffer_multisample_coverage 1
105 #define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB
106 #define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10
107 #define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11
108 #define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12
109 #endif
110 
111 #ifndef GL_EXT_packed_depth_stencil
112 #define GL_EXT_packed_depth_stencil 1
113 #define GL_DEPTH_STENCIL_EXT 0x84F9
114 #define GL_UNSIGNED_INT_24_8_EXT 0x84FA
115 #define GL_DEPTH24_STENCIL8_EXT 0x88F0
116 #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
117 #endif
118 
119 namespace osg
120 {
121 
122 /**************************************************************************
123  * RenderBuffer
124  **************************************************************************/
125 
127 {
128  public:
129  RenderBuffer();
130  RenderBuffer(int width, int height, GLenum internalFormat, int samples=0, int colorSamples=0);
131  RenderBuffer(const RenderBuffer& copy, const CopyOp& copyop = CopyOp::SHALLOW_COPY);
132 
134 
135  inline int getWidth() const;
136  inline int getHeight() const;
137  inline void setWidth(int w);
138  inline void setHeight(int h);
139  inline void setSize(int w, int h);
140  inline GLenum getInternalFormat() const;
141  inline void setInternalFormat(GLenum format);
142  inline int getSamples() const;
143  inline int getColorSamples() const;
144  inline void setSamples(int samples);
145  inline void setColorSamples(int colorSamples);
146 
147  GLuint getObjectID(unsigned int contextID, const GLExtensions *ext) const;
148  inline int compare(const RenderBuffer &rb) const;
149 
153  static void deleteRenderBuffer(unsigned int contextID, GLuint rb);
154 
157  static void flushDeletedRenderBuffers(unsigned int contextID,double currentTime, double& availableTime);
158 
162  static void discardDeletedRenderBuffers(unsigned int contextID);
163 
164  static int getMaxSamples(unsigned int contextID, const GLExtensions* ext);
165 
167  virtual void resizeGLObjectBuffers(unsigned int maxSize);
168 
172  virtual void releaseGLObjects(osg::State* = 0) const;
173 
174  protected:
175  virtual ~RenderBuffer();
176  RenderBuffer &operator=(const RenderBuffer &) { return *this; }
177 
178  inline void dirtyAll() const;
179 
180  private:
181  mutable buffered_value<GLuint> _objectID;
182  mutable buffered_value<int> _dirty;
183 
184  GLenum _internalFormat;
185  int _width;
186  int _height;
187  // "samples" in the framebuffer_multisample extension is equivalent to
188  // "coverageSamples" in the framebuffer_multisample_coverage extension.
189  int _samples;
190  int _colorSamples;
191  };
192 
193  // INLINE METHODS
194 
195  inline int RenderBuffer::getWidth() const
196  {
197  return _width;
198  }
199 
200  inline int RenderBuffer::getHeight() const
201  {
202  return _height;
203  }
204 
205  inline void RenderBuffer::setWidth(int w)
206  {
207  _width = w;
208  dirtyAll();
209  }
210 
211  inline void RenderBuffer::setHeight(int h)
212  {
213  _height = h;
214  dirtyAll();
215  }
216 
217  inline void RenderBuffer::setSize(int w, int h)
218  {
219  _width = w;
220  _height = h;
221  dirtyAll();
222  }
223 
224  inline GLenum RenderBuffer::getInternalFormat() const
225  {
226  return _internalFormat;
227  }
228 
230  {
231  _internalFormat = format;
232  dirtyAll();
233  }
234 
235  inline int RenderBuffer::getSamples() const
236  {
237  return _samples;
238  }
239 
240  inline int RenderBuffer::getColorSamples() const
241  {
242  return _colorSamples;
243  }
244 
245  inline void RenderBuffer::setSamples(int samples)
246  {
247  _samples = samples;
248  dirtyAll();
249  }
250 
251  inline void RenderBuffer::setColorSamples(int colorSamples)
252  {
253  _colorSamples = colorSamples;
254  dirtyAll();
255  }
256 
257  inline void RenderBuffer::dirtyAll() const
258  {
259  _dirty.setAllElementsTo(1);
260  }
261 
262  inline int RenderBuffer::compare(const RenderBuffer &rb) const
263  {
264  if (&rb == this) return 0;
265  if (_internalFormat < rb._internalFormat) return -1;
266  if (_internalFormat > rb._internalFormat) return 1;
267  if (_width < rb._width) return -1;
268  if (_width > rb._width) return 1;
269  if (_height < rb._height) return -1;
270  if (_height > rb._height) return 1;
271  return 0;
272  }
273 
274 /**************************************************************************
275  * FrameBufferAttachement
276  **************************************************************************/
277 class Texture1D;
278 class Texture2D;
280 class Texture3D;
281 class Texture2DArray;
282 class TextureCubeMap;
283 class TextureRectangle;
284 
286 {
287  public:
290 
291  explicit FrameBufferAttachment(RenderBuffer* target);
292  explicit FrameBufferAttachment(Texture1D* target, unsigned int level = 0);
293  explicit FrameBufferAttachment(Texture2D* target, unsigned int level = 0);
294  explicit FrameBufferAttachment(Texture2DMultisample* target, unsigned int level = 0);
295  explicit FrameBufferAttachment(Texture3D* target, unsigned int zoffset, unsigned int level = 0);
296  explicit FrameBufferAttachment(Texture2DArray* target, unsigned int layer, unsigned int level = 0);
297  explicit FrameBufferAttachment(TextureCubeMap* target, unsigned int face, unsigned int level = 0);
298  explicit FrameBufferAttachment(TextureRectangle* target);
299  explicit FrameBufferAttachment(Camera::Attachment& attachment);
300 
302 
303  FrameBufferAttachment&operator = (const FrameBufferAttachment& copy);
304 
305  bool isMultisample() const;
306  void createRequiredTexturesAndApplyGenerateMipMap(State& state, const GLExtensions* ext) const;
307  void attach(State &state, GLenum target, GLenum attachment_point, const GLExtensions* ext) const;
308  int compare(const FrameBufferAttachment &fa) const;
309 
310  RenderBuffer* getRenderBuffer();
311  const RenderBuffer* getRenderBuffer() const;
312 
313  Texture* getTexture();
314  const Texture* getTexture() const;
315 
316  unsigned int getCubeMapFace() const;
317  unsigned int getTextureLevel() const;
318  unsigned int getTexture3DZOffset() const;
319  unsigned int getTextureArrayLayer() const;
320 
321  private:
322  // use the Pimpl idiom to avoid dependency from
323  // all Texture* headers
324  struct Pimpl;
325  Pimpl* _ximpl;
326  };
327 
328 /**************************************************************************
329  * FrameBufferObject
330  **************************************************************************/
332 {
333  public:
334  typedef std::map<Camera::BufferComponent, FrameBufferAttachment> AttachmentMap;
335  typedef std::vector<GLenum> MultipleRenderingTargets;
336 
338 
340  FrameBufferObject(const FrameBufferObject& copy, const CopyOp& copyop = CopyOp::SHALLOW_COPY);
341 
342  META_StateAttribute(osg, FrameBufferObject, FRAME_BUFFER_OBJECT);
343 
344  inline const AttachmentMap& getAttachmentMap() const;
345 
346 
347  void setAttachment(BufferComponent attachment_point, const FrameBufferAttachment &attachment);
348  inline const FrameBufferAttachment& getAttachment(BufferComponent attachment_point) const;
349  inline bool hasAttachment(BufferComponent attachment_point) const;
350 
351  inline bool hasMultipleRenderingTargets() const { return !_drawBuffers.empty(); }
352  inline const MultipleRenderingTargets& getMultipleRenderingTargets() const { return _drawBuffers; }
353 
354  bool isMultisample() const;
355 
356  int compare(const StateAttribute &sa) const;
357 
358  void apply(State &state) const;
359 
360  inline GLuint getHandle(unsigned int contextID) const
361  {
362  return _fboID[contextID];
363  }
364 
366  {
367  READ_FRAMEBUFFER = GL_READ_FRAMEBUFFER_EXT,
368  DRAW_FRAMEBUFFER = GL_DRAW_FRAMEBUFFER_EXT,
369  READ_DRAW_FRAMEBUFFER = GL_FRAMEBUFFER_EXT
370  };
371 
373  void apply(State &state, BindTarget target) const;
374 
378  static void deleteFrameBufferObject(unsigned int contextID, GLuint program);
379 
382  static void flushDeletedFrameBufferObjects(unsigned int contextID,double currentTime, double& availableTime);
383 
386  static void discardDeletedFrameBufferObjects(unsigned int contextID);
387 
389  virtual void resizeGLObjectBuffers(unsigned int maxSize);
390 
394  virtual void releaseGLObjects(osg::State* = 0) const;
395 
396  protected:
397  virtual ~FrameBufferObject();
398  FrameBufferObject& operator = (const FrameBufferObject&) { return *this; }
399 
400  void updateDrawBuffers();
401 
402  inline void dirtyAll();
403 
404  GLenum convertBufferComponentToGLenum(BufferComponent attachment_point) const;
405 
406  private:
407  AttachmentMap _attachments;
408 
409  // Buffers passed to glDrawBuffers when using multiple render targets.
410  MultipleRenderingTargets _drawBuffers;
411 
412  mutable buffered_value<int> _dirtyAttachmentList;
413  mutable buffered_value<int> _unsupported;
414  mutable buffered_value<GLuint> _fboID;
415 
416  };
417 
418  // INLINE METHODS
419 
421  {
422  return _attachments;
423  }
424 
426  {
427  return _attachments.find(attachment_point) != _attachments.end();
428  }
429 
431  {
432  return _attachments.find(attachment_point)->second;
433  }
434 
436  {
437  _dirtyAttachmentList.setAllElementsTo(1);
438  }
439 
440 
441 }
442 
443 #endif
444 
int compare(const RenderBuffer &rb) const
#define GL_FRAMEBUFFER_EXT
#define OSG_EXPORT
Definition: Export.h:43
void setColorSamples(int colorSamples)
GLint GLenum internalFormat
Definition: GLU.h:71
const FrameBufferAttachment & getAttachment(BufferComponent attachment_point) const
GLenum getInternalFormat() const
BufferComponent
Definition: Camera.h:325
Camera::BufferComponent BufferComponent
#define GL_DRAW_FRAMEBUFFER_EXT
void dirtyAll() const
void setInternalFormat(GLenum format)
#define GL_READ_FRAMEBUFFER_EXT
#define META_Object(library, name)
Definition: Object.h:42
GLint GLenum GLsizei width
Definition: GLU.h:71
bool hasAttachment(BufferComponent attachment_point) const
int getHeight() const
void setAllElementsTo(const T &t)
int getColorSamples() const
int getSamples() const
GLuint getHandle(unsigned int contextID) const
#define META_StateAttribute(library, name, type)
GLint level
Definition: GLU.h:71
std::vector< GLenum > MultipleRenderingTargets
GLint GLenum GLsizei GLsizei height
Definition: GLU.h:71
const AttachmentMap & getAttachmentMap() const
Definition: AlphaFunc.h:19
bool hasMultipleRenderingTargets() const
void setSize(int w, int h)
std::map< Camera::BufferComponent, FrameBufferAttachment > AttachmentMap
void setSamples(int samples)
RenderBuffer & operator=(const RenderBuffer &)
const MultipleRenderingTargets & getMultipleRenderingTargets() const
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: GLU.h:71