From f1c7e81eb3000d454587d9eeb7ed2a14085e9340 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 15 Jun 2011 09:36:34 +0000 Subject: [PATCH] Fixed blitting of FBO's with multiple render targets. --- src/osgUtil/RenderStage.cpp | 52 ++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/src/osgUtil/RenderStage.cpp b/src/osgUtil/RenderStage.cpp index dffd83aa5..c4c3dd5df 100644 --- a/src/osgUtil/RenderStage.cpp +++ b/src/osgUtil/RenderStage.cpp @@ -954,7 +954,8 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b if (fbo_supported && _resolveFbo.valid() && fbo_ext->glBlitFramebuffer) { GLbitfield blitMask = 0; - + bool needToBlitColorBuffers = false; + //find which buffer types should be copied for (FrameBufferObject::AttachmentMap::const_iterator it = _resolveFbo->getAttachmentMap().begin(), @@ -970,9 +971,13 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b break; case Camera::PACKED_DEPTH_STENCIL_BUFFER: blitMask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; - default: + break; + case Camera::COLOR_BUFFER: blitMask |= GL_COLOR_BUFFER_BIT; break; + default: + needToBlitColorBuffers = true; + break; } } @@ -980,15 +985,42 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b _fbo->apply(state, FrameBufferObject::READ_FRAMEBUFFER); _resolveFbo->apply(state, FrameBufferObject::DRAW_FRAMEBUFFER); - // Blit to the resolve framebuffer. - // Note that (with nvidia 175.16 windows drivers at least) if the read - // framebuffer is multisampled then the dimension arguments are ignored - // and the whole framebuffer is always copied. - fbo_ext->glBlitFramebuffer( - 0, 0, static_cast(_viewport->width()), static_cast(_viewport->height()), - 0, 0, static_cast(_viewport->width()), static_cast(_viewport->height()), - blitMask, GL_NEAREST); + if (blitMask) + { + // Blit to the resolve framebuffer. + // Note that (with nvidia 175.16 windows drivers at least) if the read + // framebuffer is multisampled then the dimension arguments are ignored + // and the whole framebuffer is always copied. + fbo_ext->glBlitFramebuffer( + 0, 0, static_cast(_viewport->width()), static_cast(_viewport->height()), + 0, 0, static_cast(_viewport->width()), static_cast(_viewport->height()), + blitMask, GL_NEAREST); + } + if (needToBlitColorBuffers) + { + for (FrameBufferObject::AttachmentMap::const_iterator + it = _resolveFbo->getAttachmentMap().begin(), + end =_resolveFbo->getAttachmentMap().end(); it != end; ++it) + { + osg::Camera::BufferComponent attachment = it->first; + if (attachment >=osg::Camera::COLOR_BUFFER0) + { + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + (attachment - osg::Camera::COLOR_BUFFER0)); + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + (attachment - osg::Camera::COLOR_BUFFER0)); + + fbo_ext->glBlitFramebuffer( + 0, 0, static_cast(_viewport->width()), static_cast(_viewport->height()), + 0, 0, static_cast(_viewport->width()), static_cast(_viewport->height()), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + } + } + // reset the read and draw buffers? + // glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); + // glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + } + + apply_read_fbo = true; read_fbo = _resolveFbo.get();