diff --git a/include/osgUtil/RenderStage b/include/osgUtil/RenderStage index 15c0d2fad..199c9b47e 100644 --- a/include/osgUtil/RenderStage +++ b/include/osgUtil/RenderStage @@ -226,6 +226,8 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin GLenum _drawBuffer; GLenum _readBuffer; + // Buffers passed to glDrawBuffers when using multiple render targets. + std::vector _drawBuffers; GLbitfield _clearMask; osg::ref_ptr _colorMask; osg::Vec4 _clearColor; diff --git a/src/osgUtil/RenderStage.cpp b/src/osgUtil/RenderStage.cpp index ef03de210..79e214785 100644 --- a/src/osgUtil/RenderStage.cpp +++ b/src/osgUtil/RenderStage.cpp @@ -92,6 +92,7 @@ RenderStage::RenderStage(const RenderStage& rhs,const osg::CopyOp& copyop): _viewport(rhs._viewport), _drawBuffer(rhs._drawBuffer), _readBuffer(rhs._readBuffer), + _drawBuffers(rhs._drawBuffers), _clearMask(rhs._clearMask), _colorMask(rhs._colorMask), _clearColor(rhs._clearColor), @@ -240,7 +241,7 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo) // osg::notify(osg::NOTICE)<<"RenderStage::runCameraSetUp viewport "<<_viewport->x()<<" "<<_viewport->y()<<" "<<_viewport->width()<<" "<<_viewport->height()<setAttachment(GL_COLOR_ATTACHMENT0_EXT+(buffer-osg::Camera::COLOR_BUFFER0), osg::FrameBufferAttachment(attachment)); colorAttached = true; + + // append to MRT buffer list + _drawBuffers.push_back(GL_COLOR_ATTACHMENT0_EXT+(buffer-osg::Camera::COLOR_BUFFER0)); break; } - } } @@ -390,6 +395,7 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo) fbo_supported = false; fbo_ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); fbo = 0; + _drawBuffers.clear(); // clean up. double availableTime = 100.0f; @@ -403,11 +409,9 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo) { setDrawBuffer(GL_NONE); setReadBuffer(GL_NONE); - + _fbo = fbo; } - - } if (!fbo_supported) @@ -703,14 +707,19 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b { osg::State& state = *renderInfo.getState(); - if (_drawBuffer != GL_NONE) - { - glDrawBuffer(_drawBuffer); - } + bool using_multiple_render_targets = !(_drawBuffers.empty()); - if (_readBuffer != GL_NONE) + if (!using_multiple_render_targets) { - glReadBuffer(_readBuffer); + if (_drawBuffer != GL_NONE) + { + glDrawBuffer(_drawBuffer); + } + + if (_readBuffer != GL_NONE) + { + glReadBuffer(_readBuffer); + } } osg::FBOExtensions* fbo_ext = _fbo.valid() ? osg::FBOExtensions::instance(state.getContextID(),true) : 0; @@ -719,6 +728,15 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b if (fbo_supported) { _fbo->apply(state); + + if (using_multiple_render_targets) + { + GL2Extensions *gl2e = GL2Extensions::Get(state.getContextID(), true ); + if (gl2e) + { + gl2e->glDrawBuffers(_drawBuffers.size(), &(_drawBuffers[0])); + } + } } // do the drawing itself. @@ -751,14 +769,24 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b { if (itr->second._image.valid()) { - - if (_readBuffer != GL_NONE) + if (using_multiple_render_targets) { - glReadBuffer(_readBuffer); + int attachment=itr->first; + if (attachment==osg::Camera::DEPTH_BUFFER || attachment==osg::Camera::STENCIL_BUFFER) { + // assume first buffer rendered to is the one we want + glReadBuffer(_drawBuffers[0]); + } else { + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + (attachment - osg::Camera::COLOR_BUFFER0)); + } + } else { + if (_readBuffer != GL_NONE) + { + glReadBuffer(_readBuffer); + } } GLenum pixelFormat = itr->second._image->getPixelFormat(); - if (pixelFormat==0) pixelFormat = _imageReadPixelFormat; + if (pixelFormat==0) pixelFormat = _imageReadPixelFormat; if (pixelFormat==0) pixelFormat = GL_RGB; GLenum dataType = itr->second._image->getDataType();