fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / Window / FrameBufferObjects / OSGFrameBufferObject.cpp
blob05c3fb965022f2ac46384c0bdb8f01de3ca1369f
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
40 //---------------------------------------------------------------------------
41 // Includes
42 //---------------------------------------------------------------------------
44 #define CHECK_FRAMEBUFFER_STATUS() \
45 { \
46 GLenum status; \
48 OSGGETGLFUNC_GL3_ES( glCheckFramebufferStatus, \
49 osgGlCheckFramebufferStatus, \
50 _uiFuncCheckFramebufferStatus ); \
52 status = osgGlCheckFramebufferStatus(GL_FRAMEBUFFER); \
55 switch(status) \
56 { \
57 case GL_FRAMEBUFFER_COMPLETE: \
58 break; \
59 case GL_FRAMEBUFFER_UNSUPPORTED: \
60 FWARNING(("Unsupported Framebuffer\n")); \
61 /* choose different formats */ \
62 break; \
63 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: \
64 FWARNING(("Incomplete Attachment\n")); \
65 break; \
66 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: \
67 FWARNING(("Incomplete Missing Attachment\n")); \
68 break; \
69 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: \
70 FWARNING(("Incomplete Dimensions\n")); \
71 break; \
72 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: \
73 FWARNING(("Incomplete Formats\n")); \
74 break; \
75 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: \
76 FWARNING(("Incomplete Draw Buffer\n")); \
77 break; \
78 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: \
79 FWARNING(("Incomplete Read Buffer\n")); \
80 break; \
81 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: \
82 FWARNING(("Incomplete Multisample\n")); \
83 break; \
84 default: \
85 FWARNING(("Unknown error %x\n", status)); \
86 break; \
87 } \
91 #include <cstdlib>
92 #include <cstdio>
93 #include <boost/bind.hpp>
95 #include "OSGConfig.h"
96 #include "OSGGL.h"
97 #include "OSGGLEXT.h"
98 #include "OSGGLU.h"
99 #include "OSGGLFuncProtos.h"
101 #include "OSGWindow.h"
103 #include "OSGFrameBufferObject.h"
104 #include "OSGDrawEnv.h"
105 #include "OSGFrameBufferAttachment.h"
106 #include "OSGTextureBuffer.h"
107 #include "OSGTextureObjChunk.h"
108 #include "OSGRenderBuffer.h"
110 OSG_BEGIN_NAMESPACE
112 UInt32 FrameBufferObject::_uiFramebufferObjectArb =
113 Window::invalidExtensionID;
115 UInt32 FrameBufferObject::_uiFramebufferBlitExt =
116 Window::invalidExtensionID;
118 UInt32 FrameBufferObject::_uiPackedDepthStencilExt =
119 Window::invalidExtensionID;
121 UInt32 FrameBufferObject::_uiFuncGenFramebuffers =
122 Window::invalidFunctionID;
124 UInt32 FrameBufferObject::_uiFuncCheckFramebufferStatus =
125 Window::invalidFunctionID;
127 UInt32 FrameBufferObject::_uiFuncBindFramebuffer =
128 Window::invalidFunctionID;
130 UInt32 FrameBufferObject::_uiFuncDeleteFramebuffers =
131 Window::invalidFunctionID;
133 UInt32 FrameBufferObject::_uiFuncFramebufferRenderbuffer =
134 Window::invalidFunctionID;
136 UInt32 FrameBufferObject::_uiFuncDrawBuffers =
137 Window::invalidFunctionID;
139 UInt32 FrameBufferObject::_uiFuncBlitFramebuffer =
140 Window::invalidFunctionID;
142 // Documentation for this class is emited in the
143 // OSGFrameBufferObjectBase.cpp file.
144 // To modify it, please change the .fcd file (OSGFrameBufferObject.fcd) and
145 // regenerate the base file.
147 void FrameBufferObject::setColorAttachment(
148 FrameBufferAttachment *pAttachment,
149 UInt32 uiSlot )
151 if(uiSlot >= GL_COLOR_ATTACHMENT0)
153 uiSlot -= GL_COLOR_ATTACHMENT0;
156 editMField(ColorAttachmentsFieldMask, _mfColorAttachments);
158 if(uiSlot >= _mfColorAttachments.size())
160 _mfColorAttachments.resize(uiSlot + 1, NULL);
163 _mfColorAttachments.replace(uiSlot, pAttachment);
166 void FrameBufferObject::setSize(UInt32 uiWidth, UInt32 uiHeight)
168 setWidth (uiWidth );
169 setHeight(uiHeight);
172 void FrameBufferObject::resizeAll(UInt32 uiWidth, UInt32 uiHeight)
174 // main buffer
176 MFUnrecFrameBufferAttachmentPtr::const_iterator attIt =
177 _mfColorAttachments.begin();
178 MFUnrecFrameBufferAttachmentPtr::const_iterator attEnd =
179 _mfColorAttachments.end ();
181 for(; attIt != attEnd; ++attIt)
183 if(*attIt == NULL)
184 continue;
186 (*attIt)->resizeBuffers(uiWidth, uiHeight);
189 if(_sfDepthAttachment.getValue() != NULL)
191 _sfDepthAttachment.getValue()->resizeBuffers(uiWidth, uiHeight);
194 if(_sfStencilAttachment.getValue() != NULL)
196 _sfStencilAttachment.getValue()->resizeBuffers(uiWidth, uiHeight);
200 // multi-sample buffer
202 attIt = _mfMsaaColorAttachments.begin();
203 attEnd = _mfMsaaColorAttachments.end ();
205 for(; attIt != attEnd; ++attIt)
207 if(*attIt == NULL)
208 continue;
210 (*attIt)->resizeBuffers(uiWidth, uiHeight);
213 if(_sfMsaaDepthAttachment.getValue() != NULL)
215 _sfMsaaDepthAttachment.getValue()->resizeBuffers(uiWidth, uiHeight);
218 if(_sfMsaaStencilAttachment.getValue() != NULL)
220 _sfMsaaStencilAttachment.getValue()->resizeBuffers(uiWidth, uiHeight);
224 this->setSize(uiWidth, uiHeight);
226 Window::refreshGLObject(getGLId());
227 Window::refreshGLObject(getMultiSampleGLId());
230 /*----------------------- constructors & destructors ----------------------*/
232 FrameBufferObject::FrameBufferObject(void) :
233 Inherited()
237 FrameBufferObject::FrameBufferObject(const FrameBufferObject &source) :
238 Inherited(source)
242 FrameBufferObject::~FrameBufferObject(void)
246 /*----------------------------- class specific ----------------------------*/
248 void FrameBufferObject::initMethod(InitPhase ePhase)
250 Inherited::initMethod(ePhase);
252 if(ePhase == TypeObject::SystemPost)
254 _uiFramebufferObjectArb =
255 Window::registerExtension("GL_ARB_framebuffer_object");
256 _uiFramebufferBlitExt =
257 Window::registerExtension("GL_EXT_framebuffer_blit");
258 _uiPackedDepthStencilExt =
259 Window::registerExtension("GL_EXT_packed_depth_stencil");
261 _uiFuncGenFramebuffers =
262 Window::registerFunction (
263 OSG_DLSYM_UNDERSCORE"glGenFramebuffers",
264 _uiFramebufferObjectArb);
266 _uiFuncCheckFramebufferStatus =
267 Window::registerFunction (
268 OSG_DLSYM_UNDERSCORE"glCheckFramebufferStatus",
269 _uiFramebufferObjectArb);
271 _uiFuncBindFramebuffer =
272 Window::registerFunction (
273 OSG_DLSYM_UNDERSCORE"glBindFramebuffer",
274 _uiFramebufferObjectArb);
276 _uiFuncDeleteFramebuffers =
277 Window::registerFunction (
278 OSG_DLSYM_UNDERSCORE"glDeleteFramebuffers",
279 _uiFramebufferObjectArb);
281 _uiFuncFramebufferRenderbuffer =
282 Window::registerFunction (
283 OSG_DLSYM_UNDERSCORE"glFramebufferRenderbuffer",
284 _uiFramebufferObjectArb);
286 _uiFuncDrawBuffers =
287 Window::registerFunction (
288 OSG_DLSYM_UNDERSCORE"glDrawBuffers",
289 _uiFramebufferObjectArb);
291 _uiFuncBlitFramebuffer =
292 Window::registerFunction (
293 OSG_DLSYM_UNDERSCORE"glBlitFramebufferEXT",
294 _uiFramebufferBlitExt);
299 void FrameBufferObject::onCreate(const FrameBufferObject *source)
301 if(GlobalSystemState == Startup)
302 return;
304 setGLId(
305 Window::registerGLObject(
306 boost::bind(&FrameBufferObject::handleGL,
307 FrameBufferObjectMTUncountedPtr(this),
308 _1, _2, _3, _4),
309 &FrameBufferObject::handleDestroyGL));
311 setMultiSampleGLId(
312 Window::registerGLObject(
313 boost::bind(&FrameBufferObject::handleMultiSampleGL,
314 FrameBufferObjectMTUncountedPtr(this),
315 _1, _2, _3, _4),
316 &FrameBufferObject::handleDestroyGL));
319 void FrameBufferObject::onDestroy(UInt32 uiContainerId)
321 if(getGLId() > 0)
322 Window::destroyGLObject(getGLId(), 1);
324 if(getMultiSampleGLId() > 0)
325 Window::destroyGLObject(getMultiSampleGLId(), 1);
327 Inherited::onDestroy(uiContainerId);
330 void FrameBufferObject::changed(ConstFieldMaskArg whichField,
331 UInt32 origin,
332 BitVector details)
334 Inherited::changed(whichField, origin, details);
336 if(0x0000 != (whichField & (WidthFieldMask | HeightFieldMask)))
338 // main buffer
340 MFUnrecFrameBufferAttachmentPtr::const_iterator attIt =
341 _mfColorAttachments.begin();
342 MFUnrecFrameBufferAttachmentPtr::const_iterator attEnd =
343 _mfColorAttachments.end ();
345 for(; attIt != attEnd; ++attIt)
347 if(*attIt == NULL)
348 continue;
350 (*attIt)->resize(getWidth(), getHeight());
353 if(_sfDepthAttachment.getValue() != NULL)
355 _sfDepthAttachment.getValue()->resize(getWidth (),
356 getHeight());
359 if(_sfStencilAttachment.getValue() != NULL)
361 _sfStencilAttachment.getValue()->resize(getWidth (),
362 getHeight());
365 Window::refreshGLObject(getGLId());
368 // multi-sample buffer
370 attIt = _mfMsaaColorAttachments.begin();
371 attEnd = _mfMsaaColorAttachments.end ();
373 for(; attIt != attEnd; ++attIt)
375 if(*attIt == NULL)
376 continue;
378 (*attIt)->resize(getWidth(), getHeight());
381 if(_sfMsaaDepthAttachment.getValue() != NULL)
383 _sfMsaaDepthAttachment.getValue()->resize(getWidth (),
384 getHeight());
387 if(_sfMsaaStencilAttachment.getValue() != NULL)
389 _sfMsaaStencilAttachment.getValue()->resize(getWidth (),
390 getHeight());
393 Window::refreshGLObject(getMultiSampleGLId());
396 if(0x0000 != (whichField & DepthAttachmentFieldMask))
398 if(_sfDepthAttachment.getValue() != NULL)
400 _sfDepthAttachment.getValue()->resize(getWidth (),
401 getHeight());
403 if(_sfMsaaDepthAttachment.getValue() != NULL)
405 _sfMsaaDepthAttachment.getValue()->resize(getWidth (),
406 getHeight());
408 else if(_sfEnableMultiSample.getValue() == true)
410 FrameBufferAttachmentUnrecPtr pMsaaBuffer =
411 this->createMultiSampleBufferFrom(
412 _sfDepthAttachment.getValue());
414 this->setMsaaDepthAttachment(pMsaaBuffer);
417 else
419 this->setMsaaDepthAttachment(NULL);
422 Window::reinitializeGLObject(getGLId ());
423 Window::reinitializeGLObject(getMultiSampleGLId());
426 if(0x0000 != (whichField & StencilAttachmentFieldMask))
428 if(_sfStencilAttachment.getValue() != NULL)
430 _sfStencilAttachment.getValue()->resize(getWidth (),
431 getHeight());
433 if(_sfMsaaStencilAttachment.getValue() != NULL)
435 _sfMsaaStencilAttachment.getValue()->resize(getWidth (),
436 getHeight());
438 else if(_sfEnableMultiSample.getValue() == true)
440 FrameBufferAttachmentUnrecPtr pMsaaBuffer =
441 this->createMultiSampleBufferFrom(
442 _sfStencilAttachment.getValue());
444 this->setMsaaStencilAttachment(pMsaaBuffer);
447 else
449 this->setMsaaStencilAttachment(NULL);
452 Window::reinitializeGLObject(getGLId ());
453 Window::reinitializeGLObject(getMultiSampleGLId());
456 if(0x0000 != (whichField & ColorAttachmentsFieldMask))
458 MFUnrecFrameBufferAttachmentPtr::const_iterator attIt =
459 _mfColorAttachments.begin();
460 MFUnrecFrameBufferAttachmentPtr::const_iterator attEnd =
461 _mfColorAttachments.end ();
463 if(_mfMsaaColorAttachments.size() != _mfColorAttachments.size())
465 editMField(MsaaColorAttachmentsFieldMask, _mfMsaaColorAttachments);
467 _mfMsaaColorAttachments.resize(_mfColorAttachments.size(),
468 NULL );
471 MFUnrecFrameBufferAttachmentPtr::iterator msaaAttIt =
472 _mfMsaaColorAttachments.begin_nc();
474 for(; attIt != attEnd; ++attIt, ++msaaAttIt)
476 if(*attIt == NULL)
478 if(*msaaAttIt != NULL)
480 editMField( MsaaColorAttachmentsFieldMask,
481 _mfMsaaColorAttachments);
483 _mfMsaaColorAttachments.replace(msaaAttIt, NULL);
486 continue;
489 (*attIt)->resize(getWidth(), getHeight());
491 if(*msaaAttIt != NULL)
493 (*msaaAttIt)->resize(getWidth(), getHeight());
495 else if(_sfEnableMultiSample.getValue() == true)
497 FrameBufferAttachmentUnrecPtr pMsaaBuffer =
498 this->createMultiSampleBufferFrom(*attIt);
500 editMField( MsaaColorAttachmentsFieldMask,
501 _mfMsaaColorAttachments);
503 _mfMsaaColorAttachments.replace(msaaAttIt, pMsaaBuffer);
507 Window::reinitializeGLObject(getGLId ());
508 Window::reinitializeGLObject(getMultiSampleGLId());
511 if(0x0000 != (whichField & EnableMultiSampleFieldMask))
513 if(_sfDepthAttachment .getValue() != NULL &&
514 _sfMsaaDepthAttachment.getValue() == NULL)
516 FrameBufferAttachmentUnrecPtr pMsaaBuffer =
517 this->createMultiSampleBufferFrom(
518 _sfDepthAttachment.getValue());
520 this->setMsaaDepthAttachment(pMsaaBuffer);
523 if(_sfStencilAttachment .getValue() != NULL &&
524 _sfMsaaStencilAttachment.getValue() == NULL)
526 FrameBufferAttachmentUnrecPtr pMsaaBuffer =
527 this->createMultiSampleBufferFrom(
528 _sfStencilAttachment.getValue());
530 this->setMsaaStencilAttachment(pMsaaBuffer);
533 MFUnrecFrameBufferAttachmentPtr::const_iterator attIt =
534 _mfColorAttachments.begin();
535 MFUnrecFrameBufferAttachmentPtr::const_iterator attEnd =
536 _mfColorAttachments.end ();
538 if(_mfMsaaColorAttachments.size() != _mfColorAttachments.size())
540 editMField(MsaaColorAttachmentsFieldMask, _mfMsaaColorAttachments);
542 _mfMsaaColorAttachments.resize(_mfColorAttachments.size(),
543 NULL );
546 MFUnrecFrameBufferAttachmentPtr::iterator msaaAttIt =
547 _mfMsaaColorAttachments.begin_nc();
549 for(; attIt != attEnd; ++attIt, ++msaaAttIt)
551 if(*attIt == NULL)
552 continue;
554 if(*msaaAttIt == NULL)
556 FrameBufferAttachmentUnrecPtr pMsaaBuffer =
557 this->createMultiSampleBufferFrom(*attIt);
559 editMField( MsaaColorAttachmentsFieldMask,
560 _mfMsaaColorAttachments);
562 _mfMsaaColorAttachments.replace(msaaAttIt, pMsaaBuffer);
566 Window::reinitializeGLObject(getMultiSampleGLId());
570 void FrameBufferObject::dump( UInt32 ,
571 const BitVector ) const
573 SLOG << "Dump FrameBufferObject NI" << std::endl;
576 void FrameBufferObject::activate(DrawEnv *pEnv,
577 GLenum eDrawBuffer)
579 Window *win = pEnv->getWindow();
581 if(win->hasExtOrVersion(_uiFramebufferObjectArb, 0x0300, 0x0200) == false)
583 FNOTICE(("Framebuffer objects not supported on Window %p!\n",
584 static_cast<void *>(win)));
585 return;
588 // FLOG(("FBO Activate %p\n", this));
590 UInt32 glId = getGLId();
592 win->validateGLObject(getGLId(), pEnv);
594 if(_sfEnableMultiSample.getValue() == true &&
595 win->hasExtOrVersion(_uiFramebufferBlitExt, 0x0300) == true )
597 win->validateGLObject(getMultiSampleGLId(), pEnv);
599 glId = getMultiSampleGLId();
601 glEnable(GL_MULTISAMPLE);
604 OSGGETGLFUNCBYID_GL3_ES( glBindFramebuffer,
605 osgGlBindFramebuffer,
606 _uiFuncBindFramebuffer,
607 win);
609 osgGlBindFramebuffer(GL_FRAMEBUFFER,
610 win->getGLObjectId(glId));
612 pEnv->setActiveFBO(glId);
614 glErr("FrameBufferObject::activate::bind");
616 glErr("FrameBufferObject::activate");
618 #ifndef OSG_OGL_ES2
619 if(eDrawBuffer == GL_NONE)
621 if(_mfDrawBuffers.size() != 0)
623 OSGGETGLFUNCBYID_GL3( glDrawBuffers,
624 osgGlDrawBuffers,
625 _uiFuncDrawBuffers,
626 win);
628 osgGlDrawBuffers(GLsizei(_mfDrawBuffers.size()),
629 &(_mfDrawBuffers[0]) );
631 else
633 glDrawBuffer(GL_NONE);
634 glReadBuffer(GL_NONE);
637 else
639 OSGGETGLFUNCBYID_GL3( glDrawBuffers,
640 osgGlDrawBuffers,
641 _uiFuncDrawBuffers,
642 win);
644 osgGlDrawBuffers(1, &eDrawBuffer );
646 #endif
648 CHECK_FRAMEBUFFER_STATUS();
651 void FrameBufferObject::deactivate (DrawEnv *pEnv)
653 Window *win = pEnv->getWindow();
655 if(win->hasExtOrVersion(_uiFramebufferObjectArb, 0x0300, 0x0200) == false)
657 FNOTICE(("Framebuffer objects not supported on Window %p!\n",
658 static_cast<void *>(win)));
659 return;
662 // FLOG(("FBO DeActivate %p\n", this));
664 OSGGETGLFUNCBYID_GL3_ES( glBindFramebuffer,
665 osgGlBindFramebuffer,
666 _uiFuncBindFramebuffer,
667 win );
669 if(_sfEnableMultiSample.getValue() == true &&
670 win->hasExtOrVersion(_uiFramebufferBlitExt, 0x0300) == true )
672 OSGGETGLFUNCBYID_GL3( glBlitFramebuffer,
673 osgGlBlitFramebuffer,
674 _uiFuncBlitFramebuffer,
675 win );
677 // GLbitfield bufferMask = GL_COLOR_BUFFER_BIT;
678 glDisable(GL_MULTISAMPLE);
680 osgGlBindFramebuffer(GL_READ_FRAMEBUFFER,
681 win->getGLObjectId(getMultiSampleGLId()));
682 osgGlBindFramebuffer(GL_DRAW_FRAMEBUFFER,
683 win->getGLObjectId(getGLId ()));
685 osgGlBlitFramebuffer(0, 0, getWidth(), getHeight(),
686 0, 0, getWidth(), getHeight(),
687 (GL_COLOR_BUFFER_BIT |
688 GL_DEPTH_BUFFER_BIT |
689 GL_STENCIL_BUFFER_BIT),
690 GL_NEAREST);
692 osgGlBindFramebuffer(GL_FRAMEBUFFER, win->getGLObjectId(getGLId()));
695 if(_sfPostProcessOnDeactivate.getValue() == true)
697 MFUnrecFrameBufferAttachmentPtr::const_iterator attIt =
698 _mfColorAttachments.begin();
699 MFUnrecFrameBufferAttachmentPtr::const_iterator attEnd =
700 _mfColorAttachments.end ();
702 UInt32 index = GL_COLOR_ATTACHMENT0;
704 for(; attIt != attEnd; ++attIt, ++index)
706 if(*attIt == NULL)
707 continue;
709 (*attIt)->processPreDeactivate(pEnv, index);
712 if(_sfDepthAttachment .getValue() != NULL &&
713 _sfStencilAttachment.getValue() != NULL )
715 if(_sfDepthAttachment.getValue() == _sfStencilAttachment.getValue())
717 _sfDepthAttachment.getValue()->processPreDeactivate(
718 pEnv, GL_NONE);
720 else
722 _sfDepthAttachment .getValue()->processPreDeactivate(
723 pEnv, GL_NONE);
724 _sfStencilAttachment.getValue()->processPreDeactivate(
725 pEnv, GL_NONE);
728 else if(_sfDepthAttachment.getValue() != NULL)
730 _sfDepthAttachment .getValue()->processPreDeactivate(
731 pEnv, GL_NONE);
733 else if(_sfStencilAttachment.getValue() != NULL)
735 _sfStencilAttachment.getValue()->processPreDeactivate(
736 pEnv, GL_NONE);
740 osgGlBindFramebuffer(GL_FRAMEBUFFER, 0);
742 pEnv->setActiveFBO(0);
744 if(_sfPostProcessOnDeactivate.getValue() == true)
746 MFUnrecFrameBufferAttachmentPtr::const_iterator attIt =
747 _mfColorAttachments.begin();
748 MFUnrecFrameBufferAttachmentPtr::const_iterator attEnd =
749 _mfColorAttachments.end ();
751 for(; attIt != attEnd; ++attIt)
753 if(*attIt == NULL)
754 continue;
756 (*attIt)->processPostDeactivate(pEnv);
761 UInt32 FrameBufferObject::handleGL(DrawEnv *pEnv,
762 UInt32 osgid,
763 Window::GLObjectStatusE mode,
764 UInt64 ) const
766 Window *win = pEnv->getWindow();
767 GLuint uiFBOId = 0;
769 if(mode == Window::initialize || mode == Window::reinitialize ||
770 mode == Window::needrefresh )
772 if(mode == Window::initialize)
774 OSGGETGLFUNCBYID_GL3_ES( glGenFramebuffers,
775 osgGlGenFramebuffers,
776 _uiFuncGenFramebuffers,
777 win);
779 osgGlGenFramebuffers(1, &uiFBOId);
781 win->setGLObjectId(osgid, uiFBOId);
783 else
785 // already has an GLid
786 uiFBOId = win->getGLObjectId(osgid);
791 if(mode == Window::initialize || mode == Window::reinitialize)
793 OSGGETGLFUNCBYID_GL3_ES( glBindFramebuffer,
794 osgGlBindFramebuffer,
795 _uiFuncBindFramebuffer,
796 win);
798 OSGGETGLFUNCBYID_GL3_ES( glFramebufferRenderbuffer,
799 osgGlFramebufferRenderbuffer,
800 _uiFuncFramebufferRenderbuffer,
801 win);
803 osgGlBindFramebuffer(GL_FRAMEBUFFER, uiFBOId);
805 MFUnrecFrameBufferAttachmentPtr::const_iterator attIt =
806 _mfColorAttachments.begin();
807 MFUnrecFrameBufferAttachmentPtr::const_iterator attEnd =
808 _mfColorAttachments.end ();
810 GLint iMaxColorAttachments;
812 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &iMaxColorAttachments);
814 Int32 index = GL_COLOR_ATTACHMENT0;
816 iMaxColorAttachments += GL_COLOR_ATTACHMENT0;
818 while(attIt != attEnd && index < iMaxColorAttachments)
820 if(*attIt != NULL)
822 (*attIt)->bind(pEnv, index);
824 else
826 osgGlFramebufferRenderbuffer(GL_FRAMEBUFFER,
827 index,
828 GL_RENDERBUFFER,
832 glErr("FrameBufferObject::color");
834 ++attIt;
835 ++index;
838 while(index < iMaxColorAttachments)
840 osgGlFramebufferRenderbuffer(GL_FRAMEBUFFER,
841 index,
842 GL_RENDERBUFFER,
845 glErr("FrameBufferObject::coloroff");
847 ++index;
850 if(_sfDepthAttachment.getValue() != NULL)
852 _sfDepthAttachment.getValue()->bind(pEnv,
853 GL_DEPTH_ATTACHMENT);
855 else
857 osgGlFramebufferRenderbuffer(GL_FRAMEBUFFER,
858 GL_DEPTH_ATTACHMENT,
859 GL_RENDERBUFFER,
863 glErr("FrameBufferObject::depth");
865 if(_sfStencilAttachment.getValue() != NULL)
867 _sfStencilAttachment.getValue()->bind(pEnv,
868 GL_STENCIL_ATTACHMENT);
870 else
872 osgGlFramebufferRenderbuffer(GL_FRAMEBUFFER,
873 GL_STENCIL_ATTACHMENT,
874 GL_RENDERBUFFER,
878 glErr("FrameBufferObject::stencil");
880 else if(mode == Window::needrefresh)
882 MFUnrecFrameBufferAttachmentPtr::const_iterator attIt =
883 _mfColorAttachments.begin();
884 MFUnrecFrameBufferAttachmentPtr::const_iterator attEnd =
885 _mfColorAttachments.end ();
887 while(attIt != attEnd)
889 if(*attIt != NULL)
891 (*attIt)->validate(pEnv);
894 glErr("FrameBufferObject::refresh");
896 ++attIt;
899 if(_sfDepthAttachment.getValue() != NULL)
901 _sfDepthAttachment.getValue()->validate(pEnv);
904 if(_sfStencilAttachment.getValue() != NULL)
906 _sfStencilAttachment.getValue()->validate(pEnv);
910 return 0;
913 void FrameBufferObject::handleDestroyGL(DrawEnv *pEnv,
914 UInt32 osgid,
915 Window::GLObjectStatusE mode)
917 Window *win = pEnv->getWindow();
919 if(mode == Window::destroy)
921 GLuint uiFBOId = win->getGLObjectId(osgid);
923 if(win->hasExtOrVersion(_uiFramebufferObjectArb,
924 0x0300,
925 0x0200 ) != false)
927 OSGGETGLFUNCBYID_GL3_ES( glDeleteFramebuffers,
928 osgGlDeleteFramebuffers,
929 _uiFuncDeleteFramebuffers,
930 win);
932 osgGlDeleteFramebuffers(1, &uiFBOId);
937 UInt32 FrameBufferObject::handleMultiSampleGL(
938 DrawEnv *pEnv,
939 UInt32 osgid,
940 Window::GLObjectStatusE mode,
941 UInt64 ) const
943 Window *win = pEnv->getWindow();
944 GLuint uiFBOId = 0;
946 if(mode == Window::initialize || mode == Window::reinitialize ||
947 mode == Window::needrefresh )
949 if(mode == Window::initialize)
951 OSGGETGLFUNCBYID_GL3_ES( glGenFramebuffers,
952 osgGlGenFramebuffers,
953 _uiFuncGenFramebuffers,
954 win);
956 osgGlGenFramebuffers(1, &uiFBOId);
958 win->setGLObjectId(osgid, uiFBOId);
960 else
962 // already has an GLid
963 uiFBOId = win->getGLObjectId(osgid);
968 if(mode == Window::initialize || mode == Window::reinitialize)
970 OSGGETGLFUNCBYID_GL3_ES( glBindFramebuffer,
971 osgGlBindFramebuffer,
972 _uiFuncBindFramebuffer,
973 win);
975 OSGGETGLFUNCBYID_GL3_ES( glFramebufferRenderbuffer,
976 osgGlFramebufferRenderbuffer,
977 _uiFuncFramebufferRenderbuffer,
978 win);
980 osgGlBindFramebuffer(GL_FRAMEBUFFER, uiFBOId);
982 MFUnrecFrameBufferAttachmentPtr::const_iterator attIt =
983 _mfMsaaColorAttachments.begin();
984 MFUnrecFrameBufferAttachmentPtr::const_iterator attEnd =
985 _mfMsaaColorAttachments.end ();
987 GLint iMaxColorAttachments;
989 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &iMaxColorAttachments);
991 Int32 index = GL_COLOR_ATTACHMENT0;
993 iMaxColorAttachments += GL_COLOR_ATTACHMENT0;
995 while(attIt != attEnd && index < iMaxColorAttachments)
997 if(*attIt != NULL)
999 (*attIt)->bind(pEnv, index);
1001 else
1003 osgGlFramebufferRenderbuffer(GL_FRAMEBUFFER,
1004 index,
1005 GL_RENDERBUFFER,
1009 glErr("FrameBufferObject::color");
1011 ++attIt;
1012 ++index;
1015 while(index < iMaxColorAttachments)
1017 osgGlFramebufferRenderbuffer(GL_FRAMEBUFFER,
1018 index,
1019 GL_RENDERBUFFER,
1022 glErr("FrameBufferObject::coloroff");
1024 ++index;
1027 if(_sfMsaaDepthAttachment.getValue() != NULL)
1029 _sfMsaaDepthAttachment.getValue()->bind(pEnv,
1030 GL_DEPTH_ATTACHMENT);
1032 else
1034 osgGlFramebufferRenderbuffer(GL_FRAMEBUFFER,
1035 GL_DEPTH_ATTACHMENT,
1036 GL_RENDERBUFFER,
1040 glErr("FrameBufferObject::depth");
1042 if(_sfMsaaStencilAttachment.getValue() != NULL)
1044 _sfMsaaStencilAttachment.getValue()->bind(
1045 pEnv,
1046 GL_STENCIL_ATTACHMENT);
1048 else
1050 osgGlFramebufferRenderbuffer(GL_FRAMEBUFFER,
1051 GL_STENCIL_ATTACHMENT,
1052 GL_RENDERBUFFER,
1056 glErr("FrameBufferObject::stencil");
1058 else if(mode == Window::needrefresh)
1060 MFUnrecFrameBufferAttachmentPtr::const_iterator attIt =
1061 _mfMsaaColorAttachments.begin();
1062 MFUnrecFrameBufferAttachmentPtr::const_iterator attEnd =
1063 _mfMsaaColorAttachments.end ();
1065 while(attIt != attEnd)
1067 if(*attIt != NULL)
1069 (*attIt)->validate(pEnv);
1072 glErr("FrameBufferObject::refresh");
1074 ++attIt;
1077 if(_sfMsaaDepthAttachment.getValue() != NULL)
1079 _sfMsaaDepthAttachment.getValue()->validate(pEnv);
1082 if(_sfMsaaStencilAttachment.getValue() != NULL)
1084 _sfMsaaStencilAttachment.getValue()->validate(pEnv);
1088 return 0;
1092 FrameBufferAttachmentTransitPtr
1093 FrameBufferObject::createMultiSampleBufferFrom(FrameBufferAttachment *pSrc)
1095 RenderBufferUnrecPtr returnValue = NULL;
1097 if(pSrc == NULL)
1098 return FrameBufferAttachmentTransitPtr(returnValue);
1101 returnValue = RenderBuffer::create();
1103 returnValue->setInternalFormat(pSrc->getBufferFormat());
1105 returnValue->setWidth (pSrc->getWidth ());
1106 returnValue->setHeight(pSrc->getHeight());
1108 returnValue->setColorSamples (this->getColorSamples ());
1109 returnValue->setCoverageSamples (this->getCoverageSamples ());
1110 returnValue->setFixedSampleLocation(this->getFixedSampleLocation());
1112 return FrameBufferAttachmentTransitPtr(returnValue);
1115 void FrameBufferObject::activateFBOById(DrawEnv *pEnv, UInt32 uiOSGId)
1117 if(pEnv == NULL)
1118 return;
1120 Window *win = pEnv->getWindow();
1122 if(win->hasExtOrVersion(_uiFramebufferObjectArb, 0x0300, 0x0200) == false)
1124 FNOTICE(("Framebuffer objects not supported on Window %p!\n",
1125 static_cast<void *>(win)));
1126 return;
1129 OSGGETGLFUNCBYID_GL3_ES( glBindFramebuffer,
1130 osgGlBindFramebuffer,
1131 _uiFuncBindFramebuffer,
1132 win );
1134 win->validateGLObject(uiOSGId, pEnv);
1136 osgGlBindFramebuffer(GL_FRAMEBUFFER,
1137 win->getGLObjectId(uiOSGId));
1139 pEnv->setActiveFBO(uiOSGId);
1142 void FrameBufferObject::deactivateFBOById(DrawEnv *pEnv)
1144 Window *win = pEnv->getWindow();
1146 if(win->hasExtOrVersion(_uiFramebufferObjectArb, 0x0300, 0x0200) == false)
1148 FNOTICE(("Framebuffer objects not supported on Window %p!\n",
1149 static_cast<void *>(win)));
1150 return;
1153 OSGGETGLFUNCBYID_GL3_ES( glBindFramebuffer,
1154 osgGlBindFramebuffer,
1155 _uiFuncBindFramebuffer,
1156 win);
1158 osgGlBindFramebuffer(GL_FRAMEBUFFER,
1159 0 );
1161 pEnv->setActiveFBO(0);
1163 if(pEnv == NULL)
1164 return;
1167 OSG_END_NAMESPACE