2014年10月8日 星期三

如何將MyGUI Render到Ogre3d' compositor的RTT

由於看到Ogre Add-ons Forum的相關討論文章,於是開啟了Render MyGUI to compositor's rtt之旅Howto render MyGUI after OGRE's compositor?

檢視一下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;
}

解決方案有兩個:

  1. 參考MyGUI's的RTT example,將其Render到Ogre3d compositor's RTT(但這樣可能會造成Render兩次的問題-Main window viewport and RTT)。
  2. 自行設計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;
    }
相關Demo影片:





Dream continues in...

沒有留言:

張貼留言