I have two RenderTargets that are bound in a MultiRenderTarget.
Today, I needed to clear them with two different colors (color1 for the first, color2 for the second).
I searched a little and found out that the Viewport class (which takes care of clearing the background) is not "multi render target aware".
So I tried a few things and eventually got something working!
The idea is to create an additional viewport for each of the two render targets, and use them to clear the RTs independently (before content is rendered, using a render target listener on the MRT) :
Code: Select all
class SceneRenderTargetListener : public Ogre::RenderTargetListener
{
public :
void preRenderTargetUpdate( const Ogre::RenderTargetEvent& mEvent )
{
// Clear the FIRST render target (color1)
pRenderSystem->_setViewport(pRenderTarget1->getViewport(0));
pRenderSystem->clearFrameBuffer(Ogre::FBT_COLOUR | Ogre::FBT_DEPTH, color1);
// Clear the SECOND render target (color2)
pRenderSystem->_setViewport(pRenderTarget2->getViewport(0));
pRenderSystem->clearFrameBuffer(Ogre::FBT_COLOUR | Ogre::FBT_DEPTH, color2);
}
};
Code: Select all
// Create the two render targets
pRenderTarget1 = Ogre::TextureManager::getSingleton().createManual(
"Target1", "General", Ogre::TEX_TYPE_2D, 1024, 1024, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET
)->getBuffer()->getRenderTarget();
pRenderTarget2 = Ogre::TextureManager::getSingleton().createManual(
"Target2", "General", Ogre::TEX_TYPE_2D, 1024, 1024, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET
)->getBuffer()->getRenderTarget();
// Viewports for clearing
pRenderTarget1->addViewport(NULL);
pRenderTarget2->addViewport(NULL);
// Multi render target
pMRT_ = pRenderSystem->createMultiRenderTarget("Scene_MRT");
pMRT->addListener(new SceneRenderTargetListener());
pMRT->bindSurface(0, pRenderTarget1);
pMRT->bindSurface(1, pRenderTarget2);
// ... and its viewport
pViewport = pMRT->addViewport(pMainCamera);
pViewport->setClearEveryFrame(false);
But it's not very handy... Actually I'd prefer to write something like :
Code: Select all
pViewport->setBackgroundColor(0, color1);
pViewport->setBackgroundColor(1, color1);
Then in SceneManager::_renderScene() :
Code: Select all
// Clear the viewport if required
if (mCurrentViewport->getClearEveryFrame())
{
MultiRenderTarget* mrt = dynamic_cast<MultiRenderTarget*>(mCurrentViewport->getTarget());
if (mrt)
{
// This viewport's target is a multi render target : clear each bound targets
const MultiRenderTarget::BoundSurfaceList& rtList = mrt->getBoundSurfaceList();
MultiRenderTarget::BoundSurfaceList::const_iterator iter;
for (iter = rtList.begin(), int i = 0; iter != rtList.end(); ++iter, ++i)
{
Viewport* vp = (*iter)->addViewport(NULL, SOME_MAGIC_Z_VALUE);
mDestRenderSystem->setViewport(vp);
mDestRenderSystem->clearFrameBuffer(
mCurrentViewport->getClearBuffers(i),
mCurrentViewport->getBackgroundColour(i)
);
(*iter)->removeViewport(SOME_MAGIC_Z_VALUE);
}
mDestRenderSystem->setViewport(mCurrentViewport);
}
else
{
// This viewport's target is a simple render target : just clear it
mDestRenderSystem->clearFrameBuffer(
mCurrentViewport->getClearBuffers(),
mCurrentViewport->getBackgroundColour()
);
}
}
Of course, SOME_MAGIC_Z_VALUE is to be defined... (this viewport indexing system is not very handy, if you ask me).
NOTE : this is untested code!