From d702fed0ef2ea7b87d64ba124b547d4a732e99d7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 16 Jun 2005 11:42:59 +0000 Subject: [PATCH] Moved FBO support from osgfbo example into core osg. --- VisualStudio/examples/osgfbo/osgfbo.dsp | 16 - VisualStudio/osg/osg.dsp | 8 + examples/osgfbo/FBOExtensions.cpp | 38 --- examples/osgfbo/FBOExtensions.h | 118 -------- examples/osgfbo/FramebufferAttachment.cpp | 173 ----------- examples/osgfbo/FramebufferAttachment.h | 48 --- examples/osgfbo/FramebufferObject.cpp | 79 ----- examples/osgfbo/FramebufferObject.h | 73 ----- examples/osgfbo/GNUmakefile | 4 - examples/osgfbo/Renderbuffer.cpp | 53 ---- examples/osgfbo/Renderbuffer.h | 114 ------- examples/osgfbo/osgfbo.cpp | 13 +- include/osg/CameraNode | 16 +- include/osg/FrameBufferObject | 325 ++++++++++++++++++++ src/osg/FrameBufferObject.cpp | 346 ++++++++++++++++++++++ src/osg/GNUmakefile | 1 + 16 files changed, 700 insertions(+), 725 deletions(-) delete mode 100644 examples/osgfbo/FBOExtensions.cpp delete mode 100644 examples/osgfbo/FBOExtensions.h delete mode 100644 examples/osgfbo/FramebufferAttachment.cpp delete mode 100644 examples/osgfbo/FramebufferAttachment.h delete mode 100644 examples/osgfbo/FramebufferObject.cpp delete mode 100644 examples/osgfbo/FramebufferObject.h delete mode 100644 examples/osgfbo/Renderbuffer.cpp delete mode 100644 examples/osgfbo/Renderbuffer.h create mode 100644 include/osg/FrameBufferObject create mode 100644 src/osg/FrameBufferObject.cpp diff --git a/VisualStudio/examples/osgfbo/osgfbo.dsp b/VisualStudio/examples/osgfbo/osgfbo.dsp index 435c7c17d..25c4c4d29 100644 --- a/VisualStudio/examples/osgfbo/osgfbo.dsp +++ b/VisualStudio/examples/osgfbo/osgfbo.dsp @@ -89,22 +89,6 @@ LINK32=link.exe SOURCE=..\..\..\examples\osgfbo\osgfbo.cpp # End Source File -# Begin Source File - -SOURCE=..\..\..\examples\osgfbo\FBOExtensions.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\examples\osgfbo\FramebufferAttachment.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\examples\osgfbo\FramebufferObject.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\examples\osgfbo\Renderbuffer.cpp -# End Source File # End Target # Begin Group "Resource Files" diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index ee7d4f042..87427642c 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -236,6 +236,10 @@ SOURCE=..\..\src\osg\FragmentProgram.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\FrameBufferObject.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\FrameStamp.cpp # End Source File # Begin Source File @@ -680,6 +684,10 @@ SOURCE=..\..\include\osg\FragmentProgram # End Source File # Begin Source File +SOURCE=..\..\include\osg\FrameBufferObject +# End Source File +# Begin Source File + SOURCE=..\..\include\osg\FrameStamp # End Source File # Begin Source File diff --git a/examples/osgfbo/FBOExtensions.cpp b/examples/osgfbo/FBOExtensions.cpp deleted file mode 100644 index 982788421..000000000 --- a/examples/osgfbo/FBOExtensions.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "FBOExtensions.h" -#include - -using namespace osg; - -#define LOAD_FBO_EXT(name) name = (T##name *)getGLExtensionFuncPtr(#name); - -FBOExtensions::FBOExtensions(unsigned int contextID) -: _supported(false) -{ - if (!isGLExtensionSupported(contextID, "GL_EXT_framebuffer_object")) - return; - - LOAD_FBO_EXT(glBindRenderbufferEXT); - LOAD_FBO_EXT(glGenRenderbuffersEXT); - LOAD_FBO_EXT(glRenderbufferStorageEXT); - LOAD_FBO_EXT(glBindFramebufferEXT); - LOAD_FBO_EXT(glGenFramebuffersEXT); - LOAD_FBO_EXT(glCheckFramebufferStatusEXT); - LOAD_FBO_EXT(glFramebufferTexture1DEXT); - LOAD_FBO_EXT(glFramebufferTexture2DEXT); - LOAD_FBO_EXT(glFramebufferTexture3DEXT); - LOAD_FBO_EXT(glFramebufferRenderbufferEXT); - LOAD_FBO_EXT(glGenerateMipmapEXT); - - _supported = - glBindRenderbufferEXT != 0 && - glGenRenderbuffersEXT != 0 && - glRenderbufferStorageEXT != 0 && - glBindFramebufferEXT != 0 && - glGenFramebuffersEXT != 0 && - glCheckFramebufferStatusEXT != 0 && - glFramebufferTexture1DEXT != 0 && - glFramebufferTexture2DEXT != 0 && - glFramebufferTexture3DEXT != 0 && - glFramebufferRenderbufferEXT != 0 && - glGenerateMipmapEXT != 0; -} diff --git a/examples/osgfbo/FBOExtensions.h b/examples/osgfbo/FBOExtensions.h deleted file mode 100644 index 37da7697e..000000000 --- a/examples/osgfbo/FBOExtensions.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef OSG_FBOEXTENSIONS -#define OSG_FBOEXTENSIONS 1 - -#include -#include - -#ifndef GL_EXT_framebuffer_object -#define GL_EXT_framebuffer_object 1 -#define GL_FRAMEBUFFER_EXT 0x8D40 -#define GL_RENDERBUFFER_EXT 0x8D41 -#define GL_STENCIL_INDEX_EXT 0x8D45 -#define GL_STENCIL_INDEX1_EXT 0x8D46 -#define GL_STENCIL_INDEX4_EXT 0x8D47 -#define GL_STENCIL_INDEX8_EXT 0x8D48 -#define GL_STENCIL_INDEX16_EXT 0x8D49 -#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 -#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 -#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF -#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 -#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 -#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD -#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 -#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 -#endif - -namespace osg -{ - - class FBOExtensions - { - public: - typedef void APIENTRY TglBindRenderbufferEXT(GLenum, GLuint); - typedef void APIENTRY TglGenRenderbuffersEXT(GLsizei, GLuint *); - typedef void APIENTRY TglRenderbufferStorageEXT(GLenum, GLenum, GLsizei, GLsizei); - typedef void APIENTRY TglBindFramebufferEXT(GLenum, GLuint); - typedef void APIENTRY TglGenFramebuffersEXT(GLsizei, GLuint *); - typedef GLenum APIENTRY TglCheckFramebufferStatusEXT(GLenum); - typedef void APIENTRY TglFramebufferTexture1DEXT(GLenum, GLenum, GLenum, GLuint, GLint); - typedef void APIENTRY TglFramebufferTexture2DEXT(GLenum, GLenum, GLenum, GLuint, GLint); - typedef void APIENTRY TglFramebufferTexture3DEXT(GLenum, GLenum, GLenum, GLuint, GLint, GLint); - typedef void APIENTRY TglFramebufferRenderbufferEXT(GLenum, GLenum, GLenum, GLuint); - typedef void APIENTRY TglGenerateMipmapEXT(GLenum); - - TglBindRenderbufferEXT *glBindRenderbufferEXT; - TglGenRenderbuffersEXT *glGenRenderbuffersEXT; - TglRenderbufferStorageEXT *glRenderbufferStorageEXT; - TglBindFramebufferEXT *glBindFramebufferEXT; - TglGenFramebuffersEXT *glGenFramebuffersEXT; - TglCheckFramebufferStatusEXT *glCheckFramebufferStatusEXT; - TglFramebufferTexture1DEXT *glFramebufferTexture1DEXT; - TglFramebufferTexture2DEXT *glFramebufferTexture2DEXT; - TglFramebufferTexture3DEXT *glFramebufferTexture3DEXT; - TglFramebufferRenderbufferEXT *glFramebufferRenderbufferEXT; - TglGenerateMipmapEXT *glGenerateMipmapEXT; - - static FBOExtensions *instance(unsigned contextID) - { - static buffered_object _instances; - FBOExtensions *ext = _instances[contextID]; - if (!ext) - { - ext = new FBOExtensions(contextID); - _instances[contextID] = ext; - } - return ext; - } - - bool isSupported() const { return _supported; } - - protected: - FBOExtensions(unsigned int contextID); - - private: - bool _supported; - }; - -} - -#endif - diff --git a/examples/osgfbo/FramebufferAttachment.cpp b/examples/osgfbo/FramebufferAttachment.cpp deleted file mode 100644 index d58c3d931..000000000 --- a/examples/osgfbo/FramebufferAttachment.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "FramebufferAttachment.h" -#include "Renderbuffer.h" -#include "FBOExtensions.h" -#include -#include -#include -#include -#include -#include - -using namespace osg; - -#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_X -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#endif - -struct FramebufferAttachment::Pimpl -{ - enum TargetType - { - RENDERBUFFER, - TEXTURE1D, - TEXTURE2D, - TEXTURE3D, - TEXTURECUBE, - TEXTURERECT - }; - - TargetType targetType; - ref_ptr renderbufferTarget; - ref_ptr textureTarget; - int cubeMapFace; - int level; - int zoffset; - - explicit Pimpl(TargetType ttype = RENDERBUFFER, int lev = 0) - : targetType(ttype), - cubeMapFace(0), - level(lev), - zoffset(0) - { - } - - Pimpl(const Pimpl ©) - : targetType(copy.targetType), - renderbufferTarget(copy.renderbufferTarget), - textureTarget(copy.textureTarget), - cubeMapFace(copy.cubeMapFace), - level(copy.level), - zoffset(copy.zoffset) - { - } -}; - -FramebufferAttachment::FramebufferAttachment() -{ - _ximpl = new Pimpl; -} - -FramebufferAttachment::FramebufferAttachment(const FramebufferAttachment ©) -{ - _ximpl = new Pimpl(*copy._ximpl); -} - -FramebufferAttachment::FramebufferAttachment(Renderbuffer* target) -{ - _ximpl = new Pimpl(Pimpl::RENDERBUFFER); - _ximpl->renderbufferTarget = target; -} - -FramebufferAttachment::FramebufferAttachment(Texture1D* target, int level) -{ - _ximpl = new Pimpl(Pimpl::TEXTURE1D, level); - _ximpl->textureTarget = target; -} - -FramebufferAttachment::FramebufferAttachment(Texture2D* target, int level) -{ - _ximpl = new Pimpl(Pimpl::TEXTURE2D, level); - _ximpl->textureTarget = target; -} - -FramebufferAttachment::FramebufferAttachment(Texture3D* target, int level, int zoffset) -{ - _ximpl = new Pimpl(Pimpl::TEXTURE3D, level); - _ximpl->textureTarget = target; - _ximpl->zoffset = zoffset; -} - -FramebufferAttachment::FramebufferAttachment(TextureCubeMap* target, int face, int level) -{ - _ximpl = new Pimpl(Pimpl::TEXTURECUBE, level); - _ximpl->textureTarget = target; - _ximpl->cubeMapFace = face; -} - -FramebufferAttachment::FramebufferAttachment(TextureRectangle* target) -{ - _ximpl = new Pimpl(Pimpl::TEXTURERECT); - _ximpl->textureTarget = target; -} - -FramebufferAttachment::~FramebufferAttachment() -{ - delete _ximpl; -} - -FramebufferAttachment &FramebufferAttachment::operator = (const FramebufferAttachment ©) -{ - delete _ximpl; - _ximpl = new Pimpl(*copy._ximpl); - return *this; -} - -void FramebufferAttachment::attach(State &state, GLenum attachment_point, const FBOExtensions* ext) const -{ - unsigned int contextID = state.getContextID(); - - // force compile texture if necessary - Texture::TextureObject *tobj = 0; - if (_ximpl->textureTarget.valid()) - { - tobj = _ximpl->textureTarget->getTextureObject(contextID); - if (!tobj || tobj->_id == 0) - { - _ximpl->textureTarget->compileGLObjects(state); - tobj = _ximpl->textureTarget->getTextureObject(contextID); - } - if (!tobj || tobj->_id == 0) - return; - } - - switch (_ximpl->targetType) - { - default: - case Pimpl::RENDERBUFFER: - ext->glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_RENDERBUFFER_EXT, _ximpl->renderbufferTarget->getObjectID(contextID, ext)); - break; - case Pimpl::TEXTURE1D: - ext->glFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_TEXTURE_1D, tobj->_id, _ximpl->level); - break; - case Pimpl::TEXTURE2D: - ext->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_TEXTURE_2D, tobj->_id, _ximpl->level); - break; - case Pimpl::TEXTURE3D: - ext->glFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_TEXTURE_3D, tobj->_id, _ximpl->level, _ximpl->zoffset); - break; - case Pimpl::TEXTURERECT: - ext->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_TEXTURE_RECTANGLE, tobj->_id, 0); - break; - case Pimpl::TEXTURECUBE: - ext->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_TEXTURE_CUBE_MAP_POSITIVE_X + _ximpl->cubeMapFace, tobj->_id, _ximpl->level); - break; - } -} - -int FramebufferAttachment::compare(const FramebufferAttachment &fa) const -{ - if (&fa == this) return 0; - if (_ximpl->targetType < fa._ximpl->targetType) return -1; - if (_ximpl->targetType > fa._ximpl->targetType) return 1; - if (_ximpl->renderbufferTarget.get() < fa._ximpl->renderbufferTarget.get()) return -1; - if (_ximpl->renderbufferTarget.get() > fa._ximpl->renderbufferTarget.get()) return 1; - if (_ximpl->textureTarget.get() < fa._ximpl->textureTarget.get()) return -1; - if (_ximpl->textureTarget.get() > fa._ximpl->textureTarget.get()) return 1; - if (_ximpl->cubeMapFace < fa._ximpl->cubeMapFace) return -1; - if (_ximpl->cubeMapFace > fa._ximpl->cubeMapFace) return 1; - if (_ximpl->level < fa._ximpl->level) return -1; - if (_ximpl->level > fa._ximpl->level) return 1; - if (_ximpl->zoffset < fa._ximpl->zoffset) return -1; - if (_ximpl->zoffset > fa._ximpl->zoffset) return 1; - return 0; -} diff --git a/examples/osgfbo/FramebufferAttachment.h b/examples/osgfbo/FramebufferAttachment.h deleted file mode 100644 index 2c24b37ad..000000000 --- a/examples/osgfbo/FramebufferAttachment.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef OSG_FRAMEBUFFERATTACHMENT -#define OSG_FRAMEBUFFERATTACHMENT 1 - -#include -#include - -namespace osg -{ - - class FBOExtensions; - - class Renderbuffer; - class Texture1D; - class Texture2D; - class Texture3D; - class TextureCubeMap; - class TextureRectangle; - - class FramebufferAttachment - { - public: - FramebufferAttachment(); - FramebufferAttachment(const FramebufferAttachment ©); - - explicit FramebufferAttachment(Renderbuffer* target); - explicit FramebufferAttachment(Texture1D* target, int level = 0); - explicit FramebufferAttachment(Texture2D* target, int level = 0); - explicit FramebufferAttachment(Texture3D* target, int zoffset, int level = 0); - explicit FramebufferAttachment(TextureCubeMap* target, int face, int level = 0); - explicit FramebufferAttachment(TextureRectangle* target); - - ~FramebufferAttachment(); - - FramebufferAttachment &operator = (const FramebufferAttachment ©); - - void attach(State &state, GLenum attachment_point, const FBOExtensions* ext) const; - int compare(const FramebufferAttachment &fa) const; - - private: - // use the Pimpl idiom to avoid dependency from - // all Texture* headers - struct Pimpl; - Pimpl* _ximpl; - }; - -} - -#endif diff --git a/examples/osgfbo/FramebufferObject.cpp b/examples/osgfbo/FramebufferObject.cpp deleted file mode 100644 index a40b2061b..000000000 --- a/examples/osgfbo/FramebufferObject.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "FramebufferObject.h" -#include "FBOExtensions.h" -#include -#include - -using namespace osg; - -FramebufferObject::FramebufferObject() -: StateAttribute() -{ -} - -FramebufferObject::FramebufferObject(const FramebufferObject ©, const CopyOp ©op) -: StateAttribute(copy, copyop), - _attachments(copy._attachments) -{ -} - -void FramebufferObject::apply(State &state) const -{ - unsigned int contextID = state.getContextID(); - - if (_unsupported[contextID]) - return; - - FBOExtensions* ext = FBOExtensions::instance(contextID); - if (!ext->isSupported()) - { - _unsupported[contextID] = 1; - notify(WARN) << "Warning: EXT_framebuffer_object is not supported" << std::endl; - return; - } - - if (_attachments.empty()) - { - ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - return; - } - - int &dirtyAttachmentList = _dirtyAttachmentList[contextID]; - - GLuint &fboID = _fboID[contextID]; - if (fboID == 0) - { - ext->glGenFramebuffersEXT(1, &fboID); - if (fboID == 0) - { - notify(WARN) << "Warning: FramebufferObject: could not create the FBO" << std::endl; - return; - } - dirtyAttachmentList = 1; - } - - ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID); - - if (dirtyAttachmentList) - { - for (AttachmentMap::const_iterator i=_attachments.begin(); i!=_attachments.end(); ++i) - { - const FramebufferAttachment &fa = i->second; - fa.attach(state, i->first, ext); - } - dirtyAttachmentList = 0; - } -} - -int FramebufferObject::compare(const StateAttribute &sa) const -{ - COMPARE_StateAttribute_Types(FramebufferObject, sa); - COMPARE_StateAttribute_Parameter(_attachments.size()); - AttachmentMap::const_iterator i = _attachments.begin(); - AttachmentMap::const_iterator j = rhs._attachments.begin(); - for (; i!=_attachments.end(); ++i, ++j) - { - int cmp = i->second.compare(j->second); - if (cmp != 0) return cmp; - } - return 0; -} diff --git a/examples/osgfbo/FramebufferObject.h b/examples/osgfbo/FramebufferObject.h deleted file mode 100644 index bba60e2be..000000000 --- a/examples/osgfbo/FramebufferObject.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef OSG_FRAMEBUFFEROBJECT -#define OSG_FRAMEBUFFEROBJECT 1 - -#include -#include - -#include "FramebufferAttachment.h" - -namespace osg -{ - - class FramebufferObject: public StateAttribute - { - public: - typedef std::map AttachmentMap; - - FramebufferObject(); - FramebufferObject(const FramebufferObject ©, const CopyOp ©op = CopyOp::SHALLOW_COPY); - - META_StateAttribute(osg, FramebufferObject, (StateAttribute::Type)0x101010/*FRAMEBUFFEROBJECT*/); - - inline const AttachmentMap &getAttachmentMap() const; - inline bool hasAttachment(GLenum attachment_point) const; - inline const FramebufferAttachment& getAttachment(GLenum attachment_point) const; - inline void setAttachment(GLenum attachment_point, const FramebufferAttachment &attachment); - - int compare(const StateAttribute &sa) const; - void apply(State &state) const; - - protected: - virtual ~FramebufferObject() {} - FramebufferObject &operator=(const FramebufferObject &) { return *this; } - - inline void dirtyAll(); - - private: - AttachmentMap _attachments; - mutable buffered_value _dirtyAttachmentList; - mutable buffered_value _unsupported; - mutable buffered_value _fboID; - }; - - // INLINE METHODS - - inline const FramebufferObject::AttachmentMap &FramebufferObject::getAttachmentMap() const - { - return _attachments; - } - - inline bool FramebufferObject::hasAttachment(GLenum attachment_point) const - { - return _attachments.find(attachment_point) != _attachments.end(); - } - - inline const FramebufferAttachment &FramebufferObject::getAttachment(GLenum attachment_point) const - { - return _attachments.find(attachment_point)->second; - } - - inline void FramebufferObject::setAttachment(GLenum attachment_point, const FramebufferAttachment &attachment) - { - _attachments[attachment_point] = attachment; - dirtyAll(); - } - - inline void FramebufferObject::dirtyAll() - { - _dirtyAttachmentList.setAllElementsTo(1); - } - -} - -#endif diff --git a/examples/osgfbo/GNUmakefile b/examples/osgfbo/GNUmakefile index 129576803..82fae5dd6 100644 --- a/examples/osgfbo/GNUmakefile +++ b/examples/osgfbo/GNUmakefile @@ -2,10 +2,6 @@ TOPDIR = ../.. include $(TOPDIR)/Make/makedefs CXXFILES =\ - FBOExtensions.cpp\ - FramebufferObject.cpp\ - Renderbuffer.cpp\ - FramebufferAttachment.cpp\ osgfbo.cpp\ LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) diff --git a/examples/osgfbo/Renderbuffer.cpp b/examples/osgfbo/Renderbuffer.cpp deleted file mode 100644 index 8061ea191..000000000 --- a/examples/osgfbo/Renderbuffer.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "Renderbuffer.h" -#include "FBOExtensions.h" - -using namespace osg; - -Renderbuffer::Renderbuffer() -: Object(), - _width(512), - _height(512), - _internalFormat(GL_DEPTH_COMPONENT24) -{ -} - -Renderbuffer::Renderbuffer(int width, int height, GLenum internalFormat) -: Object(), - _width(width), - _height(height), - _internalFormat(internalFormat) -{ -} - -Renderbuffer::Renderbuffer(const Renderbuffer ©, const CopyOp ©op) -: Object(copy, copyop), - _width(copy._width), - _height(copy._height), - _internalFormat(copy._internalFormat) -{ -} - -GLuint Renderbuffer::getObjectID(unsigned int contextID, const FBOExtensions *ext) const -{ - GLuint &objectID = _objectID[contextID]; - - int &dirty = _dirty[contextID]; - - if (objectID == 0) - { - ext->glGenRenderbuffersEXT(1, &objectID); - if (objectID == 0) - return 0; - dirty = 1; - } - - if (dirty) - { - // bind and configure - ext->glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, objectID); - ext->glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, _internalFormat, _width, _height); - dirty = 0; - } - - return objectID; -} diff --git a/examples/osgfbo/Renderbuffer.h b/examples/osgfbo/Renderbuffer.h deleted file mode 100644 index 25fd4d5ef..000000000 --- a/examples/osgfbo/Renderbuffer.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef OSG_RENDERBUFFER -#define OSG_RENDERBUFFER 1 - -#include -#include -#include - -#ifndef GL_VERSION_1_4 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#endif - -namespace osg -{ - - class FBOExtensions; - - class Renderbuffer: public Object - { - public: - Renderbuffer(); - Renderbuffer(int width, int height, GLenum internalFormat); - Renderbuffer(const Renderbuffer ©, const CopyOp ©op = CopyOp::SHALLOW_COPY); - - META_Object(osg, Renderbuffer); - - inline int getWidth() const; - inline int getHeight() const; - inline void setWidth(int w); - inline void setHeight(int h); - inline void setSize(int w, int h); - inline GLenum getInternalFormat() const; - inline void setInternalFormat(GLenum format); - - GLuint getObjectID(unsigned int contextID, const FBOExtensions *ext) const; - inline int compare(const Renderbuffer &rb) const; - - protected: - virtual ~Renderbuffer() {} - Renderbuffer &operator=(const Renderbuffer &) { return *this; } - - inline void dirtyAll() const; - - private: - mutable buffered_value _objectID; - mutable buffered_value _dirty; - GLenum _internalFormat; - int _width; - int _height; - }; - - // INLINE METHODS - - inline int Renderbuffer::getWidth() const - { - return _width; - } - - inline int Renderbuffer::getHeight() const - { - return _height; - } - - inline void Renderbuffer::setWidth(int w) - { - _width = w; - dirtyAll(); - } - - inline void Renderbuffer::setHeight(int h) - { - _height = h; - dirtyAll(); - } - - inline void Renderbuffer::setSize(int w, int h) - { - _width = w; - _height = h; - dirtyAll(); - } - - inline GLenum Renderbuffer::getInternalFormat() const - { - return _internalFormat; - } - - inline void Renderbuffer::setInternalFormat(GLenum format) - { - _internalFormat = format; - dirtyAll(); - } - - inline void Renderbuffer::dirtyAll() const - { - _dirty.setAllElementsTo(1); - } - - inline int Renderbuffer::compare(const Renderbuffer &rb) const - { - if (&rb == this) return 0; - if (_internalFormat < rb._internalFormat) return -1; - if (_internalFormat > rb._internalFormat) return 1; - if (_width < rb._width) return -1; - if (_width > rb._width) return 1; - if (_height < rb._height) return -1; - if (_height > rb._height) return 1; - return 0; - } - -} - -#endif diff --git a/examples/osgfbo/osgfbo.cpp b/examples/osgfbo/osgfbo.cpp index 7662520d5..a5598efe5 100644 --- a/examples/osgfbo/osgfbo.cpp +++ b/examples/osgfbo/osgfbo.cpp @@ -10,10 +10,7 @@ #include -#include "FramebufferObject.h" -#include "FramebufferAttachment.h" -#include "Renderbuffer.h" -#include "FBOExtensions.h" +#include // This drawable class provides the means for clearing // the color and depth buffer and it is used in this @@ -81,11 +78,11 @@ void build_world(osg::Group *root) // create and configure a framebuffer object. // We attach the texture to the first color buffer, - // and we attach a simple offscreen image (Renderbuffer) + // and we attach a simple offscreen image (RenderBuffer) // to the depth buffer in order to allow depth operations - osg::ref_ptr fbo = new osg::FramebufferObject(); - fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FramebufferAttachment(tex.get())); - fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FramebufferAttachment(new osg::Renderbuffer(width, height, GL_DEPTH_COMPONENT24))); + osg::ref_ptr fbo = new osg::FrameBufferObject(); + fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(tex.get())); + fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(width, height, GL_DEPTH_COMPONENT24))); #if 0 diff --git a/include/osg/CameraNode b/include/osg/CameraNode index ec91ff086..33f870d1e 100644 --- a/include/osg/CameraNode +++ b/include/osg/CameraNode @@ -245,9 +245,22 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings typedef std::map< BufferComponent, Attachment> BufferAttachmentMap; + /** Get the BufferAttachmentMap, used to configure frame buffer objects, pbuffers and texture reads.*/ BufferAttachmentMap& getBufferAttachmentMap() { return _bufferAttachmentMap; } - const BufferAttachmentMap& getBufferAttachmentMap() const { return _bufferAttachmentMap; } + /** Get the const BufferAttachmentMap, used to configure frame buffer objects, pbuffers and texture reads.*/ + const BufferAttachmentMap& getBufferAttachmentMap() const { return _bufferAttachmentMap; } + + + /** Set the Rendering object that is used to implement rendering of the subgraph.*/ + void setRenderingCache(osg::Object* rc) { _renderingCache = rc; } + + /** Get the Rendering object that is used to implement rendering of the subgraph.*/ + osg::Object* getRenderingCache() { return _renderingCache.get(); } + + /** Get the const Rendering object that is used to implement rendering of the subgraph.*/ + const osg::Object* getRenderingCache() const { return _renderingCache.get(); } + public: @@ -277,6 +290,7 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings RenderTargetImplementation _renderTargetImplementation; BufferAttachmentMap _bufferAttachmentMap; + ref_ptr _renderingCache; }; } diff --git a/include/osg/FrameBufferObject b/include/osg/FrameBufferObject new file mode 100644 index 000000000..7cfd68ad3 --- /dev/null +++ b/include/osg/FrameBufferObject @@ -0,0 +1,325 @@ +#ifndef OSG_FRAMEBUFFEROBJECT +#define OSG_FRAMEBUFFEROBJECT 1 + +#include +#include +#include + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_STENCIL_INDEX_EXT 0x8D45 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#endif + +#ifndef GL_VERSION_1_4 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#endif + +namespace osg +{ + +/************************************************************************** + * FBOExtensions + **************************************************************************/ + + class FBOExtensions + { + public: + typedef void APIENTRY TglBindRenderbufferEXT(GLenum, GLuint); + typedef void APIENTRY TglGenRenderbuffersEXT(GLsizei, GLuint *); + typedef void APIENTRY TglRenderbufferStorageEXT(GLenum, GLenum, GLsizei, GLsizei); + typedef void APIENTRY TglBindFramebufferEXT(GLenum, GLuint); + typedef void APIENTRY TglGenFramebuffersEXT(GLsizei, GLuint *); + typedef GLenum APIENTRY TglCheckFramebufferStatusEXT(GLenum); + typedef void APIENTRY TglFramebufferTexture1DEXT(GLenum, GLenum, GLenum, GLuint, GLint); + typedef void APIENTRY TglFramebufferTexture2DEXT(GLenum, GLenum, GLenum, GLuint, GLint); + typedef void APIENTRY TglFramebufferTexture3DEXT(GLenum, GLenum, GLenum, GLuint, GLint, GLint); + typedef void APIENTRY TglFramebufferRenderbufferEXT(GLenum, GLenum, GLenum, GLuint); + typedef void APIENTRY TglGenerateMipmapEXT(GLenum); + + TglBindRenderbufferEXT *glBindRenderbufferEXT; + TglGenRenderbuffersEXT *glGenRenderbuffersEXT; + TglRenderbufferStorageEXT *glRenderbufferStorageEXT; + TglBindFramebufferEXT *glBindFramebufferEXT; + TglGenFramebuffersEXT *glGenFramebuffersEXT; + TglCheckFramebufferStatusEXT *glCheckFramebufferStatusEXT; + TglFramebufferTexture1DEXT *glFramebufferTexture1DEXT; + TglFramebufferTexture2DEXT *glFramebufferTexture2DEXT; + TglFramebufferTexture3DEXT *glFramebufferTexture3DEXT; + TglFramebufferRenderbufferEXT *glFramebufferRenderbufferEXT; + TglGenerateMipmapEXT *glGenerateMipmapEXT; + + static FBOExtensions *instance(unsigned contextID) + { + static buffered_object _instances; + FBOExtensions *ext = _instances[contextID]; + if (!ext) + { + ext = new FBOExtensions(contextID); + _instances[contextID] = ext; + } + return ext; + } + + bool isSupported() const { return _supported; } + + protected: + FBOExtensions(unsigned int contextID); + + private: + bool _supported; + }; + +/************************************************************************** + * RenderBuffer + **************************************************************************/ + + class RenderBuffer: public Object + { + public: + RenderBuffer(); + RenderBuffer(int width, int height, GLenum internalFormat); + RenderBuffer(const RenderBuffer ©, const CopyOp ©op = CopyOp::SHALLOW_COPY); + + META_Object(osg, RenderBuffer); + + inline int getWidth() const; + inline int getHeight() const; + inline void setWidth(int w); + inline void setHeight(int h); + inline void setSize(int w, int h); + inline GLenum getInternalFormat() const; + inline void setInternalFormat(GLenum format); + + GLuint getObjectID(unsigned int contextID, const FBOExtensions *ext) const; + inline int compare(const RenderBuffer &rb) const; + + protected: + virtual ~RenderBuffer() {} + RenderBuffer &operator=(const RenderBuffer &) { return *this; } + + inline void dirtyAll() const; + + private: + mutable buffered_value _objectID; + mutable buffered_value _dirty; + GLenum _internalFormat; + int _width; + int _height; + }; + + // INLINE METHODS + + inline int RenderBuffer::getWidth() const + { + return _width; + } + + inline int RenderBuffer::getHeight() const + { + return _height; + } + + inline void RenderBuffer::setWidth(int w) + { + _width = w; + dirtyAll(); + } + + inline void RenderBuffer::setHeight(int h) + { + _height = h; + dirtyAll(); + } + + inline void RenderBuffer::setSize(int w, int h) + { + _width = w; + _height = h; + dirtyAll(); + } + + inline GLenum RenderBuffer::getInternalFormat() const + { + return _internalFormat; + } + + inline void RenderBuffer::setInternalFormat(GLenum format) + { + _internalFormat = format; + dirtyAll(); + } + + inline void RenderBuffer::dirtyAll() const + { + _dirty.setAllElementsTo(1); + } + + inline int RenderBuffer::compare(const RenderBuffer &rb) const + { + if (&rb == this) return 0; + if (_internalFormat < rb._internalFormat) return -1; + if (_internalFormat > rb._internalFormat) return 1; + if (_width < rb._width) return -1; + if (_width > rb._width) return 1; + if (_height < rb._height) return -1; + if (_height > rb._height) return 1; + return 0; + } + +/************************************************************************** + * FrameBufferAttachement + **************************************************************************/ + class Texture1D; + class Texture2D; + class Texture3D; + class TextureCubeMap; + class TextureRectangle; + + class FrameBufferAttachment + { + public: + FrameBufferAttachment(); + FrameBufferAttachment(const FrameBufferAttachment ©); + + explicit FrameBufferAttachment(RenderBuffer* target); + explicit FrameBufferAttachment(Texture1D* target, int level = 0); + explicit FrameBufferAttachment(Texture2D* target, int level = 0); + explicit FrameBufferAttachment(Texture3D* target, int zoffset, int level = 0); + explicit FrameBufferAttachment(TextureCubeMap* target, int face, int level = 0); + explicit FrameBufferAttachment(TextureRectangle* target); + + ~FrameBufferAttachment(); + + FrameBufferAttachment &operator = (const FrameBufferAttachment ©); + + void attach(State &state, GLenum attachment_point, const FBOExtensions* ext) const; + int compare(const FrameBufferAttachment &fa) const; + + private: + // use the Pimpl idiom to avoid dependency from + // all Texture* headers + struct Pimpl; + Pimpl* _ximpl; + }; + +/************************************************************************** + * FrameBufferObject + **************************************************************************/ + class FrameBufferObject: public StateAttribute + { + public: + typedef std::map AttachmentMap; + + FrameBufferObject(); + FrameBufferObject(const FrameBufferObject ©, const CopyOp ©op = CopyOp::SHALLOW_COPY); + + META_StateAttribute(osg, FrameBufferObject, (StateAttribute::Type)0x101010/*FrameBufferObject*/); + + inline const AttachmentMap &getAttachmentMap() const; + inline bool hasAttachment(GLenum attachment_point) const; + inline const FrameBufferAttachment& getAttachment(GLenum attachment_point) const; + inline void setAttachment(GLenum attachment_point, const FrameBufferAttachment &attachment); + + int compare(const StateAttribute &sa) const; + void apply(State &state) const; + + protected: + virtual ~FrameBufferObject() {} + FrameBufferObject &operator=(const FrameBufferObject &) { return *this; } + + inline void dirtyAll(); + + private: + AttachmentMap _attachments; + mutable buffered_value _dirtyAttachmentList; + mutable buffered_value _unsupported; + mutable buffered_value _fboID; + }; + + // INLINE METHODS + + inline const FrameBufferObject::AttachmentMap &FrameBufferObject::getAttachmentMap() const + { + return _attachments; + } + + inline bool FrameBufferObject::hasAttachment(GLenum attachment_point) const + { + return _attachments.find(attachment_point) != _attachments.end(); + } + + inline const FrameBufferAttachment &FrameBufferObject::getAttachment(GLenum attachment_point) const + { + return _attachments.find(attachment_point)->second; + } + + inline void FrameBufferObject::setAttachment(GLenum attachment_point, const FrameBufferAttachment &attachment) + { + _attachments[attachment_point] = attachment; + dirtyAll(); + } + + inline void FrameBufferObject::dirtyAll() + { + _dirtyAttachmentList.setAllElementsTo(1); + } + + +} + +#endif + diff --git a/src/osg/FrameBufferObject.cpp b/src/osg/FrameBufferObject.cpp new file mode 100644 index 000000000..81e9d2012 --- /dev/null +++ b/src/osg/FrameBufferObject.cpp @@ -0,0 +1,346 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace osg; + + +/************************************************************************** + * FBOExtensions + **************************************************************************/ +#define LOAD_FBO_EXT(name) name = (T##name *)getGLExtensionFuncPtr(#name); + +FBOExtensions::FBOExtensions(unsigned int contextID) +: _supported(false) +{ + if (!isGLExtensionSupported(contextID, "GL_EXT_framebuffer_object")) + return; + + LOAD_FBO_EXT(glBindRenderbufferEXT); + LOAD_FBO_EXT(glGenRenderbuffersEXT); + LOAD_FBO_EXT(glRenderbufferStorageEXT); + LOAD_FBO_EXT(glBindFramebufferEXT); + LOAD_FBO_EXT(glGenFramebuffersEXT); + LOAD_FBO_EXT(glCheckFramebufferStatusEXT); + LOAD_FBO_EXT(glFramebufferTexture1DEXT); + LOAD_FBO_EXT(glFramebufferTexture2DEXT); + LOAD_FBO_EXT(glFramebufferTexture3DEXT); + LOAD_FBO_EXT(glFramebufferRenderbufferEXT); + LOAD_FBO_EXT(glGenerateMipmapEXT); + + _supported = + glBindRenderbufferEXT != 0 && + glGenRenderbuffersEXT != 0 && + glRenderbufferStorageEXT != 0 && + glBindFramebufferEXT != 0 && + glGenFramebuffersEXT != 0 && + glCheckFramebufferStatusEXT != 0 && + glFramebufferTexture1DEXT != 0 && + glFramebufferTexture2DEXT != 0 && + glFramebufferTexture3DEXT != 0 && + glFramebufferRenderbufferEXT != 0 && + glGenerateMipmapEXT != 0; +} + + +/************************************************************************** + * RenderBuffer + **************************************************************************/ + +RenderBuffer::RenderBuffer() +: Object(), + _internalFormat(GL_DEPTH_COMPONENT24), + _width(512), + _height(512) +{ +} + +RenderBuffer::RenderBuffer(int width, int height, GLenum internalFormat) +: Object(), + _internalFormat(internalFormat), + _width(width), + _height(height) +{ +} + +RenderBuffer::RenderBuffer(const RenderBuffer ©, const CopyOp ©op) +: Object(copy, copyop), + _internalFormat(copy._internalFormat), + _width(copy._width), + _height(copy._height) +{ +} + +GLuint RenderBuffer::getObjectID(unsigned int contextID, const FBOExtensions *ext) const +{ + GLuint &objectID = _objectID[contextID]; + + int &dirty = _dirty[contextID]; + + if (objectID == 0) + { + ext->glGenRenderbuffersEXT(1, &objectID); + if (objectID == 0) + return 0; + dirty = 1; + } + + if (dirty) + { + // bind and configure + ext->glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, objectID); + ext->glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, _internalFormat, _width, _height); + dirty = 0; + } + + return objectID; +} + +/************************************************************************** + * FrameBufferAttachement + **************************************************************************/ + +#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_X +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#endif + +struct FrameBufferAttachment::Pimpl +{ + enum TargetType + { + RENDERBUFFER, + TEXTURE1D, + TEXTURE2D, + TEXTURE3D, + TEXTURECUBE, + TEXTURERECT + }; + + TargetType targetType; + ref_ptr renderbufferTarget; + ref_ptr textureTarget; + int cubeMapFace; + int level; + int zoffset; + + explicit Pimpl(TargetType ttype = RENDERBUFFER, int lev = 0) + : targetType(ttype), + cubeMapFace(0), + level(lev), + zoffset(0) + { + } + + Pimpl(const Pimpl ©) + : targetType(copy.targetType), + renderbufferTarget(copy.renderbufferTarget), + textureTarget(copy.textureTarget), + cubeMapFace(copy.cubeMapFace), + level(copy.level), + zoffset(copy.zoffset) + { + } +}; + +FrameBufferAttachment::FrameBufferAttachment() +{ + _ximpl = new Pimpl; +} + +FrameBufferAttachment::FrameBufferAttachment(const FrameBufferAttachment ©) +{ + _ximpl = new Pimpl(*copy._ximpl); +} + +FrameBufferAttachment::FrameBufferAttachment(RenderBuffer* target) +{ + _ximpl = new Pimpl(Pimpl::RENDERBUFFER); + _ximpl->renderbufferTarget = target; +} + +FrameBufferAttachment::FrameBufferAttachment(Texture1D* target, int level) +{ + _ximpl = new Pimpl(Pimpl::TEXTURE1D, level); + _ximpl->textureTarget = target; +} + +FrameBufferAttachment::FrameBufferAttachment(Texture2D* target, int level) +{ + _ximpl = new Pimpl(Pimpl::TEXTURE2D, level); + _ximpl->textureTarget = target; +} + +FrameBufferAttachment::FrameBufferAttachment(Texture3D* target, int level, int zoffset) +{ + _ximpl = new Pimpl(Pimpl::TEXTURE3D, level); + _ximpl->textureTarget = target; + _ximpl->zoffset = zoffset; +} + +FrameBufferAttachment::FrameBufferAttachment(TextureCubeMap* target, int face, int level) +{ + _ximpl = new Pimpl(Pimpl::TEXTURECUBE, level); + _ximpl->textureTarget = target; + _ximpl->cubeMapFace = face; +} + +FrameBufferAttachment::FrameBufferAttachment(TextureRectangle* target) +{ + _ximpl = new Pimpl(Pimpl::TEXTURERECT); + _ximpl->textureTarget = target; +} + +FrameBufferAttachment::~FrameBufferAttachment() +{ + delete _ximpl; +} + +FrameBufferAttachment &FrameBufferAttachment::operator = (const FrameBufferAttachment ©) +{ + delete _ximpl; + _ximpl = new Pimpl(*copy._ximpl); + return *this; +} + +void FrameBufferAttachment::attach(State &state, GLenum attachment_point, const FBOExtensions* ext) const +{ + unsigned int contextID = state.getContextID(); + + // force compile texture if necessary + Texture::TextureObject *tobj = 0; + if (_ximpl->textureTarget.valid()) + { + tobj = _ximpl->textureTarget->getTextureObject(contextID); + if (!tobj || tobj->_id == 0) + { + _ximpl->textureTarget->compileGLObjects(state); + tobj = _ximpl->textureTarget->getTextureObject(contextID); + } + if (!tobj || tobj->_id == 0) + return; + } + + switch (_ximpl->targetType) + { + default: + case Pimpl::RENDERBUFFER: + ext->glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_RENDERBUFFER_EXT, _ximpl->renderbufferTarget->getObjectID(contextID, ext)); + break; + case Pimpl::TEXTURE1D: + ext->glFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_TEXTURE_1D, tobj->_id, _ximpl->level); + break; + case Pimpl::TEXTURE2D: + ext->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_TEXTURE_2D, tobj->_id, _ximpl->level); + break; + case Pimpl::TEXTURE3D: + ext->glFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_TEXTURE_3D, tobj->_id, _ximpl->level, _ximpl->zoffset); + break; + case Pimpl::TEXTURERECT: + ext->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_TEXTURE_RECTANGLE, tobj->_id, 0); + break; + case Pimpl::TEXTURECUBE: + ext->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment_point, GL_TEXTURE_CUBE_MAP_POSITIVE_X + _ximpl->cubeMapFace, tobj->_id, _ximpl->level); + break; + } +} + +int FrameBufferAttachment::compare(const FrameBufferAttachment &fa) const +{ + if (&fa == this) return 0; + if (_ximpl->targetType < fa._ximpl->targetType) return -1; + if (_ximpl->targetType > fa._ximpl->targetType) return 1; + if (_ximpl->renderbufferTarget.get() < fa._ximpl->renderbufferTarget.get()) return -1; + if (_ximpl->renderbufferTarget.get() > fa._ximpl->renderbufferTarget.get()) return 1; + if (_ximpl->textureTarget.get() < fa._ximpl->textureTarget.get()) return -1; + if (_ximpl->textureTarget.get() > fa._ximpl->textureTarget.get()) return 1; + if (_ximpl->cubeMapFace < fa._ximpl->cubeMapFace) return -1; + if (_ximpl->cubeMapFace > fa._ximpl->cubeMapFace) return 1; + if (_ximpl->level < fa._ximpl->level) return -1; + if (_ximpl->level > fa._ximpl->level) return 1; + if (_ximpl->zoffset < fa._ximpl->zoffset) return -1; + if (_ximpl->zoffset > fa._ximpl->zoffset) return 1; + return 0; +} + +/************************************************************************** + * FrameBufferObject + **************************************************************************/ + +FrameBufferObject::FrameBufferObject() +: StateAttribute() +{ +} + +FrameBufferObject::FrameBufferObject(const FrameBufferObject ©, const CopyOp ©op) +: StateAttribute(copy, copyop), + _attachments(copy._attachments) +{ +} + +void FrameBufferObject::apply(State &state) const +{ + unsigned int contextID = state.getContextID(); + + if (_unsupported[contextID]) + return; + + FBOExtensions* ext = FBOExtensions::instance(contextID); + if (!ext->isSupported()) + { + _unsupported[contextID] = 1; + notify(WARN) << "Warning: EXT_framebuffer_object is not supported" << std::endl; + return; + } + + if (_attachments.empty()) + { + ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + return; + } + + int &dirtyAttachmentList = _dirtyAttachmentList[contextID]; + + GLuint &fboID = _fboID[contextID]; + if (fboID == 0) + { + ext->glGenFramebuffersEXT(1, &fboID); + if (fboID == 0) + { + notify(WARN) << "Warning: FrameBufferObject: could not create the FBO" << std::endl; + return; + } + dirtyAttachmentList = 1; + } + + ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID); + + if (dirtyAttachmentList) + { + for (AttachmentMap::const_iterator i=_attachments.begin(); i!=_attachments.end(); ++i) + { + const FrameBufferAttachment &fa = i->second; + fa.attach(state, i->first, ext); + } + dirtyAttachmentList = 0; + } +} + +int FrameBufferObject::compare(const StateAttribute &sa) const +{ + COMPARE_StateAttribute_Types(FrameBufferObject, sa); + COMPARE_StateAttribute_Parameter(_attachments.size()); + AttachmentMap::const_iterator i = _attachments.begin(); + AttachmentMap::const_iterator j = rhs._attachments.begin(); + for (; i!=_attachments.end(); ++i, ++j) + { + int cmp = i->second.compare(j->second); + if (cmp != 0) return cmp; + } + return 0; +} diff --git a/src/osg/GNUmakefile b/src/osg/GNUmakefile index 48fd333c3..98a84cc10 100644 --- a/src/osg/GNUmakefile +++ b/src/osg/GNUmakefile @@ -39,6 +39,7 @@ CXXFILES =\ Fog.cpp\ FragmentProgram.cpp\ FrameStamp.cpp\ + FrameBufferObject.cpp\ FrontFace.cpp\ Geode.cpp\ Geometry.cpp\