From Jose Delport, added support for MRT via glDrawBuffers

This commit is contained in:
Robert Osfield 2008-04-02 17:08:40 +00:00
parent 0ab29e1502
commit db8cb2a644
2 changed files with 45 additions and 15 deletions

View File

@ -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<GLenum> _drawBuffers;
GLbitfield _clearMask;
osg::ref_ptr<osg::ColorMask> _colorMask;
osg::Vec4 _clearColor;

View File

@ -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()<<std::endl;
// osg::notify(osg::NOTICE)<<"RenderStage::runCameraSetUp computed "<<width<<" "<<height<<" "<<depth<<std::endl;
// attach an images that need to be copied after the stage is drawn.
// attach images that need to be copied after the stage is drawn.
for(itr = bufferAttachments.begin();
itr != bufferAttachments.end();
++itr)
@ -331,6 +332,8 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
bool colorAttached = false;
bool depthAttached = false;
bool stencilAttached = false;
_drawBuffers.clear(); // MRT buffers
for(osg::Camera::BufferAttachmentMap::iterator itr = bufferAttachments.begin();
itr != bufferAttachments.end();
++itr)
@ -363,9 +366,11 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
{
fbo->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;
@ -406,8 +412,6 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
_fbo = fbo;
}
}
if (!fbo_supported)
@ -703,6 +707,10 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b
{
osg::State& state = *renderInfo.getState();
bool using_multiple_render_targets = !(_drawBuffers.empty());
if (!using_multiple_render_targets)
{
if (_drawBuffer != GL_NONE)
{
glDrawBuffer(_drawBuffer);
@ -712,6 +720,7 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b
{
glReadBuffer(_readBuffer);
}
}
osg::FBOExtensions* fbo_ext = _fbo.valid() ? osg::FBOExtensions::instance(state.getContextID(),true) : 0;
bool fbo_supported = fbo_ext && fbo_ext->isSupported();
@ -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,11 +769,21 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b
{
if (itr->second._image.valid())
{
if (using_multiple_render_targets)
{
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;