檢視一下MyGUI這一段有關RenderGUI的Code,可以發現它除了Main window viewport之外,會過濾掉所view port所要求的render queue事件,原始碼如下:
void OgreRenderManager::renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& skipThisInvocation)
{
if(skipThisInvocation)
return;
Gui* gui = Gui::getInstancePtr();
if (gui == nullptr)
return;
if (Ogre::RENDER_QUEUE_OVERLAY != queueGroupId)
return;
if(m_pInterface)
{
if(m_pInterface->IsSkipRender(queueGroupId, invocation, skipThisInvocation))
return;
}
else
{
Ogre::Viewport* viewport = mSceneManager->getCurrentViewport();
if (nullptr == viewport
|| !viewport->getOverlaysEnabled())
return;
if (mWindow->getNumViewports() <= mActiveViewport
|| viewport != mWindow->getViewport(mActiveViewport))
return;
}
mCountBatch = 0;
static Timer timer;
static unsigned long last_time = timer.getMilliseconds();
unsigned long now_time = timer.getMilliseconds();
unsigned long time = now_time - last_time;
onFrameEvent((float)((double)(time) / (double)1000));
last_time = now_time;
//begin();
setManualRender(true);
onRenderToTarget(this, mUpdate);
//end();
// сбрасываем флаг
mUpdate = false;
}
解決方案有兩個:
- 參考MyGUI's的RTT example,將其Render到Ogre3d compositor's RTT(但這樣可能會造成Render兩次的問題-Main window viewport and RTT)。
- 自行設計Filter viewport 介面,Filter viewport實作導到外面。
範例程式如下:
...
if(m_pInterface)
{
if(m_pInterface->IsSkipRender(queueGroupId, invocation, kipThisInvocation))
{
return;
}
else
{
Ogre::Viewport* viewport = mSceneManager->getCurrentViewport();
if (nullptr == viewport || !viewport->getOverlaysEnabled())
return;
if (mWindow->getNumViewports() <= mActiveViewport
|| viewport != mWindow->getViewport(mActiveViewport))
return;
}
}
...
//IsSkipRender的實作:
bool CPostEffectManager::IsSkipRender(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& skipThisInvocation)
{
Ogre::SceneManager* pSceneManager =
Ogre::Root::getSingleton()._getCurrentSceneManager();
if(!pSceneManager)
return true;
Ogre::Viewport* viewport = pSceneManager->getCurrentViewport();
if(!viewport)
return true;
Ogre::RenderTarget* pRenderTarget = viewport->getTarget();
if(!pRenderTarget)
return true;
const std::string& strTargetName = pRenderTarget->getName();
//check is other custom rtt
if(strTargetName.find("MainWindow") == std::string::npos)
return true;
//is main window viewport
if(strTargetName == "MainWindow")
return m_bEnableAnyState;
//post effet rtt block
return false;
}
Dream continues in...
沒有留言:
張貼留言