天天看點

ogre渲染過程

6. RenderTarget

RenderTarget用來接收渲染操作的結果,它可以是螢幕上的視窗、離屏面(如texture)等。FPS資訊的統計也是由RenderTarget完成的。在RenderTarget每次更新完成後,将會更新統計資訊(封裝于FrameStats中)。除了負責統計幀的資訊外,RenderTarget還負責建立維護Viewport(視口):

typedef std::map<int, Viewport*, std::less<int> > ViewportList;

    ViewportList mViewportList;

    Viewport* RenderTarget::addViewport(Camera* cam, int ZOrder, float left, float top ,

        float width , float height)

    {

        ViewportList::iterator it = mViewportList.find(ZOrder);

        if (it != mViewportList.end())

        {

              …

        }

        Viewport* vp = new Viewport(cam, this, left, top, width, height, ZOrder);

        mViewportList.insert(ViewportList::value_type(ZOrder, vp));

        fireViewportAdded(vp);

        return vp;

}

由上面的代碼可以看出,每個Viewport都對應一個Camera和一個RenderTarget。當建立一個Viewport後,它會自動建立與Camera的聯系。可以把Camera看作是圖像的來源,而RenderTarget是圖像渲染的目的地。一個Viewport隻能對應一個Camera和一個RenderTarget,而一個Camera也隻能對應一個Viewport,但RenderTarget卻可以擁有幾個Viewport。

7. 渲染過程

OGRE通過WinMain或main調用go再通過Root調用startRendering進行消息循環,然後調用renderOneFrame,通過RenderSystem的_updateAllRenderTargets方法,更新所有的RenderTarget。RenderTarget通過update方法更新與之關聯的Viewport并産生FPS統計資訊。而Viewport則調用與之關聯的Camera的_renderScene方法進行渲染,Camera此時把“球”踢給SceneManager。進入SceneManager的renderScene成員函數中後,在經過計算後,把需要渲染的場景送給RenderSystem去做真正的渲染,此時我們可以看到熟悉的_breginFrame和_endFrame。一直下去經過RenderQueue、RenderQueueGroup、RenderPriorityGroup、QueuedRenderableCollection再通過通路者到達QueuedRenderableVisitor的子類SceneMgrQueuedRenderableVisitor,最終又回到SceneManager,由SceneManager再到RenderSystem完成整個渲染過程。過程僞碼如下所示:

int WinMain or main(int argc, char **argv)

{

app.go();

}

virtual void go(void)

{

     Root->startRendering();

}

void Root::startRendering(void)

{

     renderOneFrame();

}

bool Root::renderOneFrame(void)

{

     _updateAllRenderTargets();

}

void Root::_updateAllRenderTargets(void)

{

     RenderSystem->_updateAllRenderTargets();

}

void RenderSystem::_updateAllRenderTargets(void)

{

     RenderTarget->update();

}

void RenderTarget::update(void)

{

     Viewport->update();

}

void Viewport::update(void)

{

     Camera->_renderScene(this, mShowOverlays);

}

void Camera::_renderScene(Viewport *vp, bool includeOverlays)

{

     SceneManager->_renderScene(this, vp, includeOverlays);

}

void SceneManager::_renderScene(Camera* camera, Viewport* vp, bool includeOverlays)

{

    RenderSystem->_beginFrame();

    _renderVisibleObjects();

    RenderSystem->_endFrame();

}

void SceneManager::_renderVisibleObjects(void)

{

//如果有陰影

renderVisibleObjectsCustomSequence();

//否則

renderVisibleObjectsDefaultSequence();

}

void SceneManager::renderVisibleObjectsDefaultSequence(void)

{

     fireRenderQueueStarted(qId,mIlluminationStage)

     _renderQueueGroupObjects(pGroup, QueuedRenderableCollection::OM_PASS_GROUP);

     fireRenderQueueEnded(qId, mIlluminationStage)

}

void SceneManager::_renderQueueGroupObjects(RenderQueueGroup* pGroup, OrganisationMode om)

{

     renderBasicQueueGroupObjects(pGroup, om);

}

void SceneManager::renderBasicQueueGroupObjects(RenderQueueGroup* pGroup, OrganisationMode om)

{

     renderObjects(pPriorityGrp->getSolidsBasic(), om, true);

}

void SceneManager::renderObjects(const QueuedRenderableCollection& objs, …)

{

     objs.acceptVisitor(mActiveQueuedRenderableVisitor, om);

}

void QueuedRenderableCollection::acceptVisitor(QueuedRenderableVisitor* visitor…)

{

     switch(om){

     case OM_PASS_GROUP:

         acceptVisitorGrouped(visitor);

     }

}

void QueuedRenderableCollection::acceptVisitorGrouped(QueuedRenderableVisitor* visitor)

{

     QueuedRenderableVisitor->visit(Renderable);

}

void SceneManager::SceneMgrQueuedRenderableVisitor::visit(const Renderable* r)

{

     SceneManager->renderSingleObject(r, mUsedPass, autoLights, manualLightList);

}

void SceneManager::renderSingleObject(const Renderable* rend, const Pass* pass…)

{

     RenderSystem->_render(RenderOperation);

}

最終進入的RenderSystem的子類D3D9RenderSystem or GLRenderSystem。

void D3D9RenderSystem::_render(const RenderOperation& op)

{

mpD3DDevice->DrawIndexedPrimitive or mpD3DDevice->DrawPrimitive

}

void GLRenderSystem::_render(const RenderOperation& op)

{

glDrawElements or glDrawArrays

}

上一篇: ogre渲染優化
下一篇: Ogre分層渲染

繼續閱讀