root/OpenSceneGraph/trunk/include/osg/FrameBufferObject @ 13041

Revision 13041, 20.2 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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_DEPTH_COMPONENT
112#define GL_DEPTH_COMPONENT              0x1902
113#endif
114
115#ifndef GL_VERSION_1_4
116#define GL_DEPTH_COMPONENT16              0x81A5
117#define GL_DEPTH_COMPONENT24              0x81A6
118#define GL_DEPTH_COMPONENT32              0x81A7
119#endif
120
121#ifndef GL_DEPTH_COMPONENT32F
122#define GL_DEPTH_COMPONENT32F             0x8CAC
123#endif
124
125#ifndef GL_DEPTH_COMPONENT32F_NV
126#define GL_DEPTH_COMPONENT32F_NV          0x8DAB
127#endif
128
129#ifndef GL_EXT_packed_depth_stencil
130#define GL_EXT_packed_depth_stencil 1
131#define GL_DEPTH_STENCIL_EXT 0x84F9
132#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
133#define GL_DEPTH24_STENCIL8_EXT 0x88F0
134#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
135#endif
136
137namespace osg
138{
139
140/**************************************************************************
141 * FBOExtensions
142 **************************************************************************/
143
144    class OSG_EXPORT FBOExtensions : public osg::Referenced
145    {
146    public:
147        typedef void GL_APIENTRY TglBindRenderbuffer(GLenum, GLuint);
148        typedef void GL_APIENTRY TglDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers);
149        typedef void GL_APIENTRY TglGenRenderbuffers(GLsizei, GLuint *);
150        typedef void GL_APIENTRY TglRenderbufferStorage(GLenum, GLenum, GLsizei, GLsizei);
151        typedef void GL_APIENTRY TglRenderbufferStorageMultisample(GLenum, GLsizei, GLenum, GLsizei, GLsizei);
152        typedef void GL_APIENTRY TglRenderbufferStorageMultisampleCoverageNV(GLenum, GLsizei, GLsizei, GLenum, GLsizei, GLsizei);
153        typedef void GL_APIENTRY TglBindFramebuffer(GLenum, GLuint);
154        typedef void GL_APIENTRY TglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
155        typedef void GL_APIENTRY TglGenFramebuffers(GLsizei, GLuint *);
156        typedef GLenum GL_APIENTRY TglCheckFramebufferStatus(GLenum);
157        typedef void GL_APIENTRY TglFramebufferTexture1D(GLenum, GLenum, GLenum, GLuint, GLint);
158        typedef void GL_APIENTRY TglFramebufferTexture2D(GLenum, GLenum, GLenum, GLuint, GLint);
159        typedef void GL_APIENTRY TglFramebufferTexture3D(GLenum, GLenum, GLenum, GLuint, GLint, GLint);
160        typedef void GL_APIENTRY TglFramebufferTexture(GLenum, GLenum, GLint, GLint);
161        typedef void GL_APIENTRY TglFramebufferTextureLayer(GLenum, GLenum, GLuint, GLint, GLint);
162        typedef void GL_APIENTRY TglFramebufferRenderbuffer(GLenum, GLenum, GLenum, GLuint);
163        typedef void GL_APIENTRY TglGenerateMipmap(GLenum);
164        typedef void GL_APIENTRY TglBlitFramebuffer(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum);
165        typedef void GL_APIENTRY TglGetRenderbufferParameteriv(GLenum, GLenum, GLint*);
166
167        TglBindRenderbuffer* glBindRenderbuffer;
168        TglGenRenderbuffers* glGenRenderbuffers;
169        TglDeleteRenderbuffers* glDeleteRenderbuffers;
170        TglRenderbufferStorage* glRenderbufferStorage;
171        TglRenderbufferStorageMultisample* glRenderbufferStorageMultisample;
172        TglRenderbufferStorageMultisampleCoverageNV* glRenderbufferStorageMultisampleCoverageNV;
173        TglBindFramebuffer* glBindFramebuffer;
174        TglDeleteFramebuffers* glDeleteFramebuffers;
175        TglGenFramebuffers* glGenFramebuffers;
176        TglCheckFramebufferStatus* glCheckFramebufferStatus;
177        TglFramebufferTexture1D* glFramebufferTexture1D;
178        TglFramebufferTexture2D* glFramebufferTexture2D;
179        TglFramebufferTexture3D* glFramebufferTexture3D;
180        TglFramebufferTexture* glFramebufferTexture;
181        TglFramebufferTextureLayer* glFramebufferTextureLayer;
182        TglFramebufferRenderbuffer* glFramebufferRenderbuffer;
183        TglGenerateMipmap* glGenerateMipmap;
184        TglBlitFramebuffer* glBlitFramebuffer;
185        TglGetRenderbufferParameteriv* glGetRenderbufferParameteriv;
186
187        static FBOExtensions* instance(unsigned contextID, bool createIfNotInitalized);
188
189        bool isSupported() const { return _supported; }
190        bool isMultisampleSupported() const { return glRenderbufferStorageMultisample != 0; }
191        bool isMultisampleCoverageSupported() const { return glRenderbufferStorageMultisampleCoverageNV != 0; }
192        bool isPackedDepthStencilSupported() const { return _packed_depth_stencil_supported; }
193
194    protected:
195        FBOExtensions(unsigned int contextID);
196
197        bool _supported;
198        bool _packed_depth_stencil_supported;
199    };
200
201/**************************************************************************
202 * RenderBuffer
203 **************************************************************************/
204
205    class OSG_EXPORT RenderBuffer: public Object
206    {
207    public:
208        RenderBuffer();
209        RenderBuffer(int width, int height, GLenum internalFormat, int samples=0, int colorSamples=0);
210        RenderBuffer(const RenderBuffer& copy, const CopyOp& copyop = CopyOp::SHALLOW_COPY);
211
212        META_Object(osg, RenderBuffer);
213
214        inline int getWidth() const;
215        inline int getHeight() const;
216        inline void setWidth(int w);
217        inline void setHeight(int h);
218        inline void setSize(int w, int h);
219        inline GLenum getInternalFormat() const;
220        inline void setInternalFormat(GLenum format);
221        inline int getSamples() const;
222        inline int getColorSamples() const;
223        inline void setSamples(int samples);
224        inline void setColorSamples(int colorSamples);
225
226        GLuint getObjectID(unsigned int contextID, const FBOExtensions *ext) const;
227        inline int compare(const RenderBuffer &rb) const;
228
229        /** Mark internal RenderBuffer for deletion.
230          * Deletion requests are queued until they can be executed
231          * in the proper GL context. */
232        static void deleteRenderBuffer(unsigned int contextID, GLuint rb);
233
234        /** flush all the cached RenderBuffers which need to be deleted
235          * in the OpenGL context related to contextID.*/
236        static void flushDeletedRenderBuffers(unsigned int contextID,double currentTime, double& availableTime);
237
238        /** discard all the cached RenderBuffers which need to be deleted in the OpenGL context related to contextID.
239          * Note, unlike flush no OpenGL calls are made, instead the handles are all removed.
240          * this call is useful for when an OpenGL context has been destroyed. */
241        static void discardDeletedRenderBuffers(unsigned int contextID);
242
243        static int getMaxSamples(unsigned int contextID, const FBOExtensions *ext);
244
245        /** Resize any per context GLObject buffers to specified size. */
246        virtual void resizeGLObjectBuffers(unsigned int maxSize);
247
248        /** If State is non-zero, this function releases any associated OpenGL objects for
249           * the specified graphics context. Otherwise, releases OpenGL objexts
250           * for all graphics contexts. */
251        virtual void releaseGLObjects(osg::State* = 0) const;
252
253    protected:
254        virtual ~RenderBuffer();
255        RenderBuffer &operator=(const RenderBuffer &) { return *this; }
256
257        inline void dirtyAll() const;
258
259    private:
260        mutable buffered_value<GLuint> _objectID;
261        mutable buffered_value<int> _dirty;
262
263        GLenum _internalFormat;
264        int _width;
265        int _height;
266        // "samples" in the framebuffer_multisample extension is equivalent to
267        // "coverageSamples" in the framebuffer_multisample_coverage extension.
268        int _samples;
269        int _colorSamples;
270    };
271
272    // INLINE METHODS
273
274    inline int RenderBuffer::getWidth() const
275    {
276        return _width;
277    }
278
279    inline int RenderBuffer::getHeight() const
280    {
281        return _height;
282    }
283
284    inline void RenderBuffer::setWidth(int w)
285    {
286        _width = w;
287        dirtyAll();
288    }
289
290    inline void RenderBuffer::setHeight(int h)
291    {
292        _height = h;
293        dirtyAll();
294    }
295
296    inline void RenderBuffer::setSize(int w, int h)
297    {
298        _width = w;
299        _height = h;
300        dirtyAll();
301    }
302
303    inline GLenum RenderBuffer::getInternalFormat() const
304    {
305        return _internalFormat;
306    }
307
308    inline void RenderBuffer::setInternalFormat(GLenum format)
309    {
310        _internalFormat = format;
311        dirtyAll();
312    }
313
314    inline int RenderBuffer::getSamples() const
315    {
316        return _samples;
317    }
318
319    inline int RenderBuffer::getColorSamples() const
320    {
321        return _colorSamples;
322    }
323
324    inline void RenderBuffer::setSamples(int samples)
325    {
326        _samples = samples;
327        dirtyAll();
328    }
329
330    inline void RenderBuffer::setColorSamples(int colorSamples)
331    {
332        _colorSamples = colorSamples;
333        dirtyAll();
334    }
335
336    inline void RenderBuffer::dirtyAll() const
337    {
338        _dirty.setAllElementsTo(1);
339    }
340
341    inline int RenderBuffer::compare(const RenderBuffer &rb) const
342    {
343        if (&rb == this) return 0;
344        if (_internalFormat < rb._internalFormat) return -1;
345        if (_internalFormat > rb._internalFormat) return 1;
346        if (_width < rb._width) return -1;
347        if (_width > rb._width) return 1;
348        if (_height < rb._height) return -1;
349        if (_height > rb._height) return 1;
350        return 0;
351    }
352
353/**************************************************************************
354 * FrameBufferAttachement
355 **************************************************************************/
356    class Texture1D;
357    class Texture2D;
358    class Texture2DMultisample;
359    class Texture3D;
360    class Texture2DArray;
361    class TextureCubeMap;
362    class TextureRectangle;
363
364    class OSG_EXPORT FrameBufferAttachment
365    {
366    public:
367        FrameBufferAttachment();
368        FrameBufferAttachment(const FrameBufferAttachment& copy);
369
370        explicit FrameBufferAttachment(RenderBuffer* target);
371        explicit FrameBufferAttachment(Texture1D* target, unsigned int level = 0);
372        explicit FrameBufferAttachment(Texture2D* target, unsigned int level = 0);
373        explicit FrameBufferAttachment(Texture2DMultisample* target, unsigned int level = 0);
374        explicit FrameBufferAttachment(Texture3D* target, unsigned int zoffset, unsigned int level = 0);
375        explicit FrameBufferAttachment(Texture2DArray* target, unsigned int layer, unsigned int level = 0);
376        explicit FrameBufferAttachment(TextureCubeMap* target, unsigned int face, unsigned int level = 0);
377        explicit FrameBufferAttachment(TextureRectangle* target);
378        explicit FrameBufferAttachment(Camera::Attachment& attachment);
379
380        ~FrameBufferAttachment();
381
382        FrameBufferAttachment&operator = (const FrameBufferAttachment& copy);
383
384        bool isMultisample() const;
385        void createRequiredTexturesAndApplyGenerateMipMap(State& state, const FBOExtensions* ext) const;
386        void attach(State &state, GLenum target, GLenum attachment_point, const FBOExtensions* ext) const;
387        int compare(const FrameBufferAttachment &fa) const;
388
389        RenderBuffer* getRenderBuffer();
390        const RenderBuffer* getRenderBuffer() const;
391
392        Texture* getTexture();
393        const Texture* getTexture() const;
394
395        unsigned int getCubeMapFace() const;
396        unsigned int getTextureLevel() const;
397        unsigned int getTexture3DZOffset() const;
398        unsigned int getTextureArrayLayer() const;
399
400    private:
401        // use the Pimpl idiom to avoid dependency from
402        // all Texture* headers
403        struct Pimpl;
404        Pimpl* _ximpl;
405    };
406
407/**************************************************************************
408 * FrameBufferObject
409 **************************************************************************/
410    class OSG_EXPORT FrameBufferObject: public StateAttribute
411    {
412    public:
413        typedef std::map<Camera::BufferComponent, FrameBufferAttachment> AttachmentMap;
414        typedef std::vector<GLenum> MultipleRenderingTargets;
415
416        typedef Camera::BufferComponent BufferComponent;
417
418        FrameBufferObject();
419        FrameBufferObject(const FrameBufferObject& copy, const CopyOp& copyop = CopyOp::SHALLOW_COPY);
420
421        META_StateAttribute(osg, FrameBufferObject, (StateAttribute::Type)0x101010/*FrameBufferObject*/);
422
423        inline const AttachmentMap& getAttachmentMap() const;
424
425
426        void setAttachment(BufferComponent attachment_point, const FrameBufferAttachment &attachment);
427        inline const FrameBufferAttachment& getAttachment(BufferComponent attachment_point) const;
428        inline bool hasAttachment(BufferComponent attachment_point) const;
429
430        inline bool hasMultipleRenderingTargets() const { return !_drawBuffers.empty(); }
431        inline const MultipleRenderingTargets& getMultipleRenderingTargets() const { return _drawBuffers; }
432
433        bool isMultisample() const;
434
435        int compare(const StateAttribute &sa) const;
436
437        void apply(State &state) const;
438
439        enum BindTarget
440        {
441            READ_FRAMEBUFFER = GL_READ_FRAMEBUFFER_EXT,
442            DRAW_FRAMEBUFFER = GL_DRAW_FRAMEBUFFER_EXT,
443            READ_DRAW_FRAMEBUFFER = GL_FRAMEBUFFER_EXT
444        };
445
446        /** Bind the FBO as either the read or draw target, or both. */
447        void apply(State &state, BindTarget target) const;
448
449        /** Mark internal FBO for deletion.
450          * Deletion requests are queued until they can be executed
451          * in the proper GL context. */
452        static void deleteFrameBufferObject(unsigned int contextID, GLuint program);
453
454        /** flush all the cached FBOs which need to be deleted
455          * in the OpenGL context related to contextID.*/
456        static void flushDeletedFrameBufferObjects(unsigned int contextID,double currentTime, double& availableTime);
457
458        /** discard all the cached FBOs which need to be deleted
459          * in the OpenGL context related to contextID.*/
460        static void discardDeletedFrameBufferObjects(unsigned int contextID);
461
462        /** Resize any per context GLObject buffers to specified size. */
463        virtual void resizeGLObjectBuffers(unsigned int maxSize);
464
465        /** If State is non-zero, this function releases any associated OpenGL objects for
466           * the specified graphics context. Otherwise, releases OpenGL objexts
467           * for all graphics contexts. */
468        virtual void releaseGLObjects(osg::State* = 0) const;
469
470    protected:
471        virtual ~FrameBufferObject();
472        FrameBufferObject& operator = (const FrameBufferObject&) { return *this; }
473
474        void updateDrawBuffers();
475
476        inline void dirtyAll();
477
478        GLenum convertBufferComponentToGLenum(BufferComponent attachment_point) const;
479
480    private:
481        AttachmentMap               _attachments;
482
483        // Buffers passed to glDrawBuffers when using multiple render targets.
484        MultipleRenderingTargets    _drawBuffers;
485
486        mutable buffered_value<int>         _dirtyAttachmentList;
487        mutable buffered_value<int>         _unsupported;
488        mutable buffered_value<GLuint>      _fboID;
489
490    };
491
492    // INLINE METHODS
493
494    inline const FrameBufferObject::AttachmentMap &FrameBufferObject::getAttachmentMap() const
495    {
496        return _attachments;
497    }
498
499    inline bool FrameBufferObject::hasAttachment(FrameBufferObject::BufferComponent attachment_point) const
500    {
501        return _attachments.find(attachment_point) != _attachments.end();
502    }
503
504    inline const FrameBufferAttachment &FrameBufferObject::getAttachment(FrameBufferObject::BufferComponent attachment_point) const
505    {
506        return _attachments.find(attachment_point)->second;
507    }
508
509    inline void FrameBufferObject::dirtyAll()
510    {
511        _dirtyAttachmentList.setAllElementsTo(1);
512    }
513
514
515}
516
517#endif
518
Note: See TracBrowser for help on using the browser.