青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

麒麟子

~~

導航

<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

統計

常用鏈接

留言簿(12)

隨筆分類

隨筆檔案

Friends

WebSites

積分與排名

最新隨筆

最新評論

閱讀排行榜

評論排行榜

OGRE主要渲染流程簡介

OGRE主要渲染流程簡介

                                    謝偉亮       feiyurainy@163.com

                               轉載請注明出處

    很早以前就想寫一些關于OGRE的文章了,一直沒機會。

    理解一個渲染引擎,我覺得最重要的是先抓住了它的主架構,它的主線,渲染流程,不然的話,一個引擎幾萬行,甚至幾十萬行的代碼,光是打開solution就能嚇你一跳了,OGRE也有十幾萬行的代碼量,我一開始看它的時候也是無從下手,感覺代碼太多了,不知道從哪開始看好,這個class看看,那個class看看,由于對整個引擎沒有一個清晰的認識,看過了也印象不深,所以,最后,還是決定先找出它的主線,了解它的渲染流程,這樣才能有機地把各個部分聯系起來。

    這篇短文也是對OGRE的主要渲染流程的一個介紹,可能對一些class不會太多地去介紹具體的實現細節。我所用的代碼都是取自于OGRE的最新的CVS版本。

    讀者最好對OGRE有一定的了解,至少得看懂它的example,不然可能一些東西理解起來比較困難。對D3DOPENGL有一定了解更好。

    如果你看過D3D SDK中帶的例子,你一定知道一個比較簡單的3D程序要運行起來,至少都會涉及以下的幾部分:

    首先是數據的來源,包括頂點數據,紋理數據等,這些數據可以從文件中讀取,也可以在程序運行時生成。

    接下來,我們會建立頂點緩沖區把頂點保存起來,建立texture對象來表示texture,對頂點組成的物體設置它在世界坐標系下的坐標,設置攝像機的位置,視點,設置viewport的位置和大小,然后就可以在渲染循環中開始調用渲染操作了,經過了front bufferback buffer的交換,我們就能在屏幕上看到3D圖形了,偽代碼如下:

      setupVertexBuffer

      setWorldTransform

      setCamera

      setProjectionTransform

      setViewport

       beginFrame

      setTexture

      drawObject

      endFrame 

     以下就是渲染一個物體的主要步驟,在我看來,這就是3D程序的主線,同樣道理,無論你多復雜的渲染引擎,都得實現上述的這些步驟,其他的一些效果如陰影,光照等,都是附著在這條主線上的,所以,如果你能在你所研究的渲染引擎上也清晰地看到這條主線,可能對你深入地研究它會大有幫助,下面,我們就一起來找到OGRE中的這條主線。

     OGRE的渲染循環都是起源于Root::renderOneFrame,這個函數在OGRE自帶的example中是不會顯式調用的,因為example都調用了Root::startRendering,由startRendering來調用renderOneFrame,如果你用OGRE來寫真正的游戲,或者編輯器,你可能就需要在的消息主循環中調用renderOneFrame了,顧名思義,這個函數就是對整個OGRE進行一幀的更新,包括動畫,渲染狀態的改變,渲染api的調用等,在這個函數中,會包括了我們上述偽代碼的幾乎全部內容,所以是本文的重點所在。

     進入renderOneFrame,可以看到頭尾兩個fire函數,這種函數在OGRE中經常出現,一般都是fire…startfire…end一起出現的,在這些函數中,可能會處理一些用戶自定義的操作,如_fireFrameStarted就會對所以的frameListener進行處理,這些fire函數可以暫時不用理會,繼續看_updateAllRenderTargets,在這個函數中,會委派當前所用的renderer對所有創建出來的render target進行updaterender target也就是渲染的目的地,一般會有兩種,一種是render texture,一種是render buffer,接著進入RenderSystem::_updateAllRenderTargets,可以看到在render system中,對創建出來的render target是用RenderTargetPriorityMap來保存的,以便按照一定的順序來對render target進行update,因為在渲染物體到render buffer時,一般會用到之前渲染好的render texture,所以render texture形式的render target需要在render buffer之前進行更新。

     進入render targetupdate,可以看到,它仍然把update操作繼續傳遞下去,調用所有掛在這個render target上的viewportupdate

     Viewport其實就是定義了render target上的一塊要進行更新的區域,所以一個render target是可以掛多個viewport的,以實現多人對戰時分屏,或者是畫中畫等效果,可以把OGRE中的viewport看成是保存camerarendertarget這兩者的組合,把viewport中所定義的camera所看到的場景內容渲染到viewport所定義的render target的區域里。

     Viewport還有一個重要信息是ZOrder,可以看到RenderTarget中的ViewportList帶有一個比較函數,所以在RenderTarget::update中,ZOrder越小的,越先被渲染,所以,如果兩個viewport所定義的區域互相重疊了,而且ZOrder又不一樣,最終的效果就是ZOrder小的viewport的內容會被ZOrder大的viewport的內容所覆蓋。

     繼續進入Viewport::update,就像前面所說,它調用它所引用的camera來渲染整個場景,而在Camera::_renderScene中,是調用SceneManager::_renderScene(Camera* camera, Viewport* vp, bool includeOverlays)SceneManager::_renderScene里就是具體的渲染流程了。從函數名稱還有參數也可以看出來,這個函數的作用就是利用所指定的cameraviewport,來把場景中的內容渲染到viewport所指定的render target的某塊區域中。根據camera,我們可以定出view matrixprojection matrix,還可以進行視錐剔除,只渲染看得見的物體。注意,我們這里只看標準的SceneManager的方法,不看BspSceneManager派生類的方法,而且,我們會拋開跟主線無關的內容,如對shadowsetup,骨骼動畫的播放,shader參數的傳遞等,因為我們只注重渲染的主流程。

     在SceneManager::_renderScene中所應看的第一個重要函數是_updateSceneGraphOGRE對場景的組織是通過節點樹來組織的,一個節點,你可以看成是空間中的某些變換的組合,如位置,縮放,旋轉等,這些變換,會作用到掛接在這些節點上的具體的物體的信息,也就是說,節點保存了world transform,對具體的物體,如一個人,在空間中的定位,都是通過操作節點來完成的。同時節點還保存了一個世界坐標的AABB,這個AABB能容納所有它所掛接的物體的大小,主要是用于視錐裁減的,如果當前攝像機看不見某個節點的AABB,那么說明攝像機看不見節點所掛接的所有物體,所以在渲染時可以對這個節點視而不見。

     _updateSceneGraph的內部處理比較繁瑣,我們只需知道,經過了_updateSceneGraph,場景節點樹中的每個節點都經過了更新,包括位置,縮放,和方位,還有節點的包圍盒。

     繼續回到SceneManager::_renderScene,接下來要看的是setViewport,它會調用具體的renderersetviewport的操作,設置viewport中所掛接的render target為當前所要渲染的目標,viewport中的區域為當前所要渲染的目標中的區域。

     接下來要碰到OGRE渲染流程中的一個重要的概念,Render Queue。這個東西實在內容比較多,還是以后有機會單獨提出來說吧,你可以簡單把它想成是一個容器,里面的元素就是renderable,每個renderable可以看成是每次調用drawprimitive函數所渲染的物體,可以是一個模型,也可以是模型的一部分。在RenderQueue中,它會按材質來分組這些renderable,還會對renderable進行排序。

     在每一次調用SceneManager::_renderScene時,都會調用SceneManager::prepareRenderQueue來清理RenderQueue,然后再調用SceneManager::__findVisibleObjects來把當前攝像機所能看見的物體都加入到RenderQueue中。

     SceneManager::__findVisibleObjects是一個遞歸的處理過程,它從場景的根節點開始,先檢查攝像機是否能看見這個節點的包圍盒(包圍盒在_updateSceneGraph時已經計算好了),如果看不見,那么這個節點,還有它的子節點都不用管了。如果能看見,再檢測掛在這個節點上的所有MovableObject,如果當前所檢測的MovableObject是可見的,就會調用它的_updateRenderQueue方法,一般在這個方法里就可以把和這個MovableObject相關的renderable送入RenderQueue了。

     這里要說說MovableObjectMovableObject主要是用于表示場景中離散的物體,如Entity,顧名思義,能移動的物體,不過它的“能移動”這個能力是要通過SceneNode來實現的,所以MovableObject來能顯示出來,首先得先掛接在某個場景節點上,通過場景節點來定位。你可以控制MovableObject的一些屬性,如某個MovableObject是否要顯示,是否要隱藏,都可以通過MovableObject::setVisible方法來實現。

     檢測完該節點上的MovableObject之后,就繼續調用所有子節點的_findVisibleObjects方法,一直遞歸下去。這樣,就能把場景中所有要渲染的renderable所加入到RenderQueue中了。

     至此,我們就擁有了要渲染的物體的信息了,接下來就是對這些物體進行渲染了,你會發現跟D3DOpenGL的代碼很類似的調用:

       mDestRenderSystem->clearFrameBuffer

      mDestRenderSystem->_beginFrame   

       mDestRenderSystem->_setProjectionMatrix

       mDestRenderSystem->_setViewMatrix

       _renderVisibleObjects();

      mDestRenderSystem->_endFrame();

     這些api的作用和D3D中的類似調用的作用都差不多,這里再說一下_renderVisibleObjects(),在這個函數中,會對RenderQueue中的每個renderable進行渲染,用的是visitor模式來遍歷操作每個renderable,最終在SceneManager::renderSingleObject中取出每個renderable所保存的頂點,索引,世界矩陣等信息,來進行渲染。這其中還包括了查找離該renderable最近的光源等操作,比較復雜。

     到這里,SceneManager::_renderScene的流程基本走完了,也就是說,OGRE一幀中的渲染流程差不多也結束了,你應該也發現,這個流程跟你用D3D寫一個簡單程序的流程基本是一樣的,在這個流程的基礎上,再去看具體的實現,如怎么樣設置紋理,怎么樣調用你熟悉的D3DOpenGLAPI來渲染物體,應該會簡單得多。

     對OGRE的渲染流程的大概介紹到這里也結束了,很多細節都沒涉及,以后有機會再寫吧。

posted on 2009-05-17 23:56 麒麟子 閱讀(890) 評論(1)  編輯 收藏 引用 所屬分類: Game and Engine

評論

# re: OGRE主要渲染流程簡介 2010-05-29 15:21 小柳

很好,謝謝了!  回復  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲裸体视频| 韩国视频理论视频久久| 99re6这里只有精品| 亚洲欧洲另类| 欧美午夜电影一区| 欧美一区二区三区在线播放| 亚洲在线一区二区三区| 国产欧美一区二区三区在线老狼 | 欧美激情成人在线| 欧美成人a视频| 亚洲欧美在线看| 久久精品国产欧美激情| 亚洲美女福利视频网站| 亚洲性xxxx| 在线播放不卡| 99re视频这里只有精品| 久久久综合网| 欧美精品一区二区三区在线看午夜| 99re6热只有精品免费观看| 亚洲一级二级| 亚洲高清网站| 亚洲一二三区精品| 亚洲国产精品久久久久婷婷884| 亚洲国产欧美一区二区三区久久 | 久久亚洲综合| 亚洲一级高清| 麻豆乱码国产一区二区三区| 亚洲一卡二卡三卡四卡五卡| 欧美在线国产| 夜夜爽av福利精品导航| 欧美一区国产二区| 亚洲性图久久| 欧美高清日韩| 玖玖综合伊人| 国产精品丝袜久久久久久app| 另类成人小视频在线| 欧美香蕉大胸在线视频观看| 欧美黑人在线播放| 狠狠色狠色综合曰曰| 一区二区欧美精品| 亚洲精品色婷婷福利天堂| 午夜伦欧美伦电影理论片| 一区二区三区鲁丝不卡| 久久久久久久久久看片| 欧美一区二区三区视频免费| 欧美日韩mp4| 欧美激情久久久久久| 国产日韩在线一区| 亚洲一区二区黄| 一区二区欧美亚洲| 欧美肥婆bbw| 亚洲成人资源网| 影音先锋欧美精品| 久久国产66| 久久久久青草大香线综合精品| 国产精品xxx在线观看www| 亚洲精品中文字幕在线观看| 亚洲大胆人体视频| 久久久亚洲影院你懂的| 久久男人资源视频| 国产午夜精品美女毛片视频| 亚洲综合不卡| 久久福利影视| 国内一区二区三区| 久久久久9999亚洲精品| 久久青草久久| 亚洲大片一区二区三区| 久久综合色一综合色88| 欧美韩日精品| 日韩视频一区二区三区在线播放| 男女精品视频| 亚洲精品美女在线观看播放| 99在线精品免费视频九九视| 欧美日韩dvd在线观看| 一区二区三区不卡视频在线观看| 亚洲一区二区三区精品视频| 国产精品久久久久99| 亚洲欧美综合v| 美日韩精品视频| 亚洲欧洲一区二区三区久久| 欧美精品三级日韩久久| 亚洲免费久久| 精品成人一区二区三区四区| 亚洲激情在线观看| 日韩视频不卡| 国产精品成人av性教育| 亚洲视频一区在线| 久久狠狠亚洲综合| 在线精品福利| 欧美性大战xxxxx久久久| 欧美一区二区观看视频| 欧美激情区在线播放| 亚洲私人影院| 国语自产精品视频在线看8查询8| 美日韩精品视频免费看| 99精品视频一区| 久久久欧美精品sm网站| 亚洲精品乱码久久久久久日本蜜臀 | 国产一区二区三区在线观看免费视频 | 亚洲午夜视频| 黄色成人在线| 欧美日韩亚洲一区二区| 性欧美video另类hd性玩具| 欧美黄色aaaa| 久久国产精品久久久久久| 亚洲国产另类精品专区| 国产精品成人aaaaa网站| 狂野欧美一区| 亚洲欧美日韩在线播放| 亚洲激情视频网| 久久九九电影| 亚洲免费婷婷| 亚洲精品免费在线| 黄色av成人| 国产精品盗摄一区二区三区| 美日韩精品免费| 欧美一级大片在线免费观看| 亚洲美女少妇无套啪啪呻吟| 欧美1区2区| 久久久久久久综合日本| 亚洲欧美日韩网| 日韩视频一区二区三区在线播放免费观看 | 国产精品青草久久| 欧美日韩高清区| 欧美成年网站| 久久综合精品一区| 久久精品中文字幕一区二区三区| 中文av字幕一区| 99亚洲视频| 99精品黄色片免费大全| 亚洲国产日韩欧美一区二区三区| 久久综合伊人77777| 欧美中文字幕在线视频| 午夜在线播放视频欧美| 亚洲视频axxx| 国产精品99久久99久久久二8 | 亚洲黄色高清| 久久夜色精品一区| 欧美另类极品videosbest最新版本 | 欧美激情一区| 欧美成va人片在线观看| 免费亚洲电影| 欧美成人免费一级人片100| 免费久久精品视频| 欧美国产91| 亚洲欧洲在线观看| 亚洲精品女av网站| 欧美激情第五页| 亚洲国产精品久久久久秋霞蜜臀 | 亚洲人成网站影音先锋播放| 亚洲国产欧美日韩另类综合| 91久久精品久久国产性色也91| 亚洲成人资源| 一区二区三区导航| 性亚洲最疯狂xxxx高清| 欧美在线观看视频在线| 久久综合综合久久综合| 欧美精品激情在线| 国产精品美女www爽爽爽视频| 国产精品私房写真福利视频| 国内欧美视频一区二区| 亚洲国产高潮在线观看| aa日韩免费精品视频一| 亚洲欧美www| 久久九九热免费视频| 亚洲丰满在线| 亚洲欧美日韩一区在线| 久久一区二区精品| 欧美日韩色一区| 国产日韩亚洲欧美精品| 在线观看视频免费一区二区三区| 亚洲精品一区二区三区樱花| 亚洲欧美综合| 欧美国产一区二区三区激情无套| 日韩香蕉视频| 久久嫩草精品久久久久| 欧美三级视频在线| 精品999成人| 亚洲一级影院| 欧美顶级艳妇交换群宴| 在线视频精品一区| 蜜乳av另类精品一区二区| 国产精品高潮粉嫩av| 亚洲国产清纯| 久久久91精品国产一区二区三区 | 久久人人爽爽爽人久久久| 欧美日韩综合在线免费观看| 在线播放视频一区| 亚洲欧美日韩人成在线播放| 米奇777超碰欧美日韩亚洲| 夜夜嗨av一区二区三区四区| 久久天天躁狠狠躁夜夜av| 美腿丝袜亚洲色图| 亚洲视频在线观看视频| 欧美久久久久| 亚洲欧洲在线一区| 久久亚洲视频| 欧美亚洲视频在线观看| 欧美亚男人的天堂| 一本色道久久加勒比88综合|