diff --git a/include/osg/FrameBufferObject b/include/osg/FrameBufferObject index 6be5110f3..7b681de01 100644 --- a/include/osg/FrameBufferObject +++ b/include/osg/FrameBufferObject @@ -295,8 +295,10 @@ namespace osg class OSG_EXPORT FrameBufferObject: public StateAttribute { public: - typedef std::map AttachmentMap; + typedef std::map AttachmentMap; typedef std::vector MultipleRenderingTargets; + + typedef Camera::BufferComponent BufferComponent; FrameBufferObject(); FrameBufferObject(const FrameBufferObject& copy, const CopyOp& copyop = CopyOp::SHALLOW_COPY); @@ -304,10 +306,19 @@ namespace osg META_StateAttribute(osg, FrameBufferObject, (StateAttribute::Type)0x101010/*FrameBufferObject*/); inline const AttachmentMap& getAttachmentMap() const; - inline bool hasAttachment(GLenum attachment_point) const; + void setAttachment(GLenum attachment_point, const FrameBufferAttachment &attachment); inline const FrameBufferAttachment& getAttachment(GLenum attachment_point) const; + inline bool hasAttachment(GLenum attachment_point) const; + + void setAttachment(BufferComponent attachment_point, const FrameBufferAttachment &attachment); + inline const FrameBufferAttachment& getAttachment(BufferComponent attachment_point) const; + inline bool hasAttachment(BufferComponent attachment_point) const; + + GLenum convertBufferComponentToGLenum(BufferComponent attachment_point) const; + BufferComponent convertGLenumToBufferComponent(GLenum attachment_point) const; + inline bool hasMultipleRenderingTargets() const { return !_drawBuffers.empty(); } inline const MultipleRenderingTargets& getMultipleRenderingTargets() const { return _drawBuffers; } @@ -333,6 +344,8 @@ namespace osg virtual ~FrameBufferObject(); FrameBufferObject& operator = (const FrameBufferObject&) { return *this; } + void updateDrawBuffers(); + inline void dirtyAll(); private: @@ -355,11 +368,21 @@ namespace osg } inline bool FrameBufferObject::hasAttachment(GLenum attachment_point) const + { + return hasAttachment(convertGLenumToBufferComponent(attachment_point)); + } + + inline bool FrameBufferObject::hasAttachment(FrameBufferObject::BufferComponent attachment_point) const { return _attachments.find(attachment_point) != _attachments.end(); } inline const FrameBufferAttachment &FrameBufferObject::getAttachment(GLenum attachment_point) const + { + return getAttachment(convertGLenumToBufferComponent(attachment_point)); + } + + inline const FrameBufferAttachment &FrameBufferObject::getAttachment(FrameBufferObject::BufferComponent attachment_point) const { return _attachments.find(attachment_point)->second; } diff --git a/src/osg/FrameBufferObject.cpp b/src/osg/FrameBufferObject.cpp index 720b285b8..9d10eb8a7 100644 --- a/src/osg/FrameBufferObject.cpp +++ b/src/osg/FrameBufferObject.cpp @@ -571,8 +571,43 @@ FrameBufferObject::~FrameBufferObject() void FrameBufferObject::setAttachment(GLenum attachment_point, const FrameBufferAttachment &attachment) { + setAttachment(convertGLenumToBufferComponent(attachment_point),attachment); +} + +void FrameBufferObject::setAttachment(BufferComponent attachment_point, const FrameBufferAttachment &attachment) +{ + GLenum gl_attachment = convertBufferComponentToGLenum(attachment_point); _attachments[attachment_point] = attachment; + updateDrawBuffers(); + dirtyAll(); +} + + +GLenum FrameBufferObject::convertBufferComponentToGLenum(BufferComponent attachment_point) const +{ + switch(attachment_point) + { + case(Camera::DEPTH_BUFFER): return GL_DEPTH_ATTACHMENT_EXT; + case(Camera::STENCIL_BUFFER): return GL_STENCIL_ATTACHMENT_EXT; + case(Camera::COLOR_BUFFER): return GL_COLOR_ATTACHMENT0_EXT; + default: return GLenum(GL_COLOR_ATTACHMENT0_EXT + (attachment_point-Camera::COLOR_BUFFER0)); + } +} + +FrameBufferObject::BufferComponent FrameBufferObject::convertGLenumToBufferComponent(GLenum attachment_point) const +{ + switch(attachment_point) + { + case(GL_DEPTH_ATTACHMENT_EXT): return Camera::DEPTH_BUFFER; + case(GL_STENCIL_ATTACHMENT_EXT): return Camera::STENCIL_BUFFER; + case(GL_COLOR_ATTACHMENT0_EXT): return Camera::COLOR_BUFFER; + default: return BufferComponent(Camera::COLOR_BUFFER0+(attachment_point-GL_COLOR_ATTACHMENT0_EXT)); + } +} + +void FrameBufferObject::updateDrawBuffers() +{ _drawBuffers.clear(); // create textures and mipmaps before we bind the frame buffer object @@ -581,12 +616,9 @@ void FrameBufferObject::setAttachment(GLenum attachment_point, const FrameBuffer const FrameBufferAttachment &fa = i->second; // setup draw buffers based on the attachment definition - if (i->first >= GL_COLOR_ATTACHMENT0_EXT && i->first <= GL_COLOR_ATTACHMENT15_EXT) - _drawBuffers.push_back(i->first); + if (i->first >= Camera::COLOR_BUFFER0 && i->first <= Camera::COLOR_BUFFER15) + _drawBuffers.push_back(convertBufferComponentToGLenum(i->first)); } - - - dirtyAll(); } void FrameBufferObject::apply(State &state) const @@ -663,7 +695,7 @@ void FrameBufferObject::apply(State &state) const for (AttachmentMap::const_iterator i=_attachments.begin(); i!=_attachments.end(); ++i) { const FrameBufferAttachment &fa = i->second; - fa.attach(state, i->first, ext); + fa.attach(state, convertBufferComponentToGLenum(i->first), ext); } dirtyAttachmentList = 0; } diff --git a/src/osgUtil/RenderStage.cpp b/src/osgUtil/RenderStage.cpp index 6f8aaed9a..f42170644 100644 --- a/src/osgUtil/RenderStage.cpp +++ b/src/osgUtil/RenderStage.cpp @@ -340,43 +340,21 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo) osg::Camera::BufferComponent buffer = itr->first; osg::Camera::Attachment& attachment = itr->second; - switch(buffer) - { - case(osg::Camera::DEPTH_BUFFER): - { - fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(attachment)); - depthAttached = true; - break; - } - case(osg::Camera::STENCIL_BUFFER): - { - fbo->setAttachment(GL_STENCIL_ATTACHMENT_EXT, osg::FrameBufferAttachment(attachment)); - stencilAttached = true; - break; - } - case(osg::Camera::COLOR_BUFFER): - { - fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(attachment)); - colorAttached = true; - break; - } - default: - { - fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT+(buffer-osg::Camera::COLOR_BUFFER0), osg::FrameBufferAttachment(attachment)); - colorAttached = true; - break; - } - } + fbo->setAttachment(buffer, osg::FrameBufferAttachment(attachment)); + + if (buffer==osg::Camera::DEPTH_BUFFER) depthAttached = true; + else if (buffer==osg::Camera::STENCIL_BUFFER) stencilAttached = true; + else if (buffer>osg::Camera::COLOR_BUFFER) colorAttached = true; } if (!depthAttached) { - fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(width, height, GL_DEPTH_COMPONENT24))); + fbo->setAttachment(osg::Camera::DEPTH_BUFFER, osg::FrameBufferAttachment(new osg::RenderBuffer(width, height, GL_DEPTH_COMPONENT24))); } if (!colorAttached) { - fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(width, height, GL_RGB))); + fbo->setAttachment(osg::Camera::COLOR_BUFFER, osg::FrameBufferAttachment(new osg::RenderBuffer(width, height, GL_RGB))); } fbo->apply(state); @@ -385,7 +363,7 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo) if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - osg::notify(osg::INFO)<<"RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x"<glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);