• <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>
            隨筆 - 505  文章 - 1034  trackbacks - 0
            <2006年7月>
            2526272829301
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345


            子曾經(jīng)曰過:編程無他,唯手熟爾!

            常用鏈接

            留言簿(94)

            隨筆分類(649)

            隨筆檔案(505)

            相冊

            BCB

            Crytek

            • crymod
            • Crytek's Offical Modding Portal

            Game Industry

            OGRE

            other

            Programmers

            Qt

            WOW Stuff

            搜索

            •  

            積分與排名

            • 積分 - 914431
            • 排名 - 14

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜

            【1. 概覽】
            Ogre支持Quake3的bsp格式。相關(guān)的代碼在“Plugin_BSPSceneManager”工程中。主要的類有以下幾個:



            Class BspSceneNode:

            BspSceneNode是SceneNode的派生類,是專門提供給BSPSceneManager使用的。主要是提供針對于BSP tree的可見性判斷。這個類并不是BSP tree的node,BSP tree中的node使用BspNode。BspSceneNode會放入BSP tree的leaf節(jié)點中。由于SceneNode使用包裹盒的方法,不可分割,所以一個BspSceneNode可能放入多個Bsp tree的leaf節(jié)點中。

            從類的定義看,BspSceneNode并沒有額外的保存什么數(shù)據(jù)。重寫的幾個虛函數(shù)主要是用來通知BspSceneMapager, BspSceneNode::_update()會調(diào)用BspSceneManager::_notifyObjectMoved(),detach objcect會調(diào)用BspSceneManager::_notifyObjectDetached()。



            Class BspSceneManager:

            粗略的看BspSceneManager與OctreeSceneManager類似。首先保存了一個BspLevel的指針,然后使用一個 walkTree()函數(shù),用來遍歷tree結(jié)構(gòu)。由于Quake使用BSP leaf tree,所以多了一個processVisibleLeaf()函數(shù)。另外一個明顯的不同是有一個renderStaticGeometry()函數(shù), “Renders the static level geometry tagged in walkTree”。此函數(shù)渲染“mMatFaceGroupMap”中的所有數(shù)據(jù)。BSP一個好處是不透明面可以front-back的順序來渲染,而透明面back-front來渲染,OGRE是如何將此特性保存到MaterialFaceGroupMap的呢?



            Class BspLevel:

            這是一個核心的class。他存儲了BSP的所有數(shù)據(jù),關(guān)鍵的數(shù)據(jù)有:

            <!--[if !supportLists]-->1. <!--[endif]-->“BspNode* mRootNode;”――BSP tree的根節(jié)點

            <!--[if !supportLists]-->2. <!--[endif]-->“VertexData* mVertexData;”――整個level的所有頂點;

            <!--[if !supportLists]-->3. <!--[endif]-->“StaticFaceGroup* mFaceGroups;”――faces

            <!--[if !supportLists]-->4. <!--[endif]-->“BspNode::Brush *mBrushes;”――用來做碰撞檢測的Brush,是QuakeBSP除了渲染以外的另外一個精華!Brush的名字有點怪,其實就是一個convex volume,可以減少CD的運算量。

            <!--[if !supportLists]-->5. <!--[endif]-->“VisData mVisData;”――PVS數(shù)據(jù),是又一個Quake中的精華!當(dāng)初Carmark在設(shè)計Quake的時候還使用軟件渲染,hiden surface removal和減少over draw是最另他頭痛的問題。BSP的思想應(yīng)該是他從網(wǎng)上看來的,不過PVS應(yīng)該是他所創(chuàng)。PVS大大減少了over draw。(見《Michael Abrash's Graphics Programming Black Book》)

            <!--[if !supportLists]-->6. <!--[endif]-->“PatchMap mPatches;”――Quake3支持貝賽爾曲面

            關(guān)鍵的函數(shù):

            <!--[if !supportLists]-->1. <!--[endif]-->bool isLeafVisible(const BspNode* from, const BspNode* to) const;使用PVS來檢測可見性。

            <!--[if !supportLists]-->2. <!--[endif]-->void _notifyObjectMoved(const MovableObject* mov, const Vector3& pos);
            void _notifyObjectDetached(const MovableObject* mov);
            à void tagNodesWithMovable(BspNode* node, const MovableObject* mov, const Vector3& pos);
            把MovableObject(注意:不是SceneNode)掛到BSP的leaves上。



            Class BspNode:

            這是Bsp中的另外一個重要的類了。Node和Leaf都使用這個類。

            重要數(shù)據(jù):

            <!--[if !supportLists]-->1. <!--[endif]-->Plane mSplitPlane; BspNode* mFront; BspNode* mBack;
            分割平面和前后節(jié)點;

            <!--[if !supportLists]-->2. <!--[endif]-->int mVisCluster;
            每個cluster占pvs的一個bit,這是為了減少pvs占用的內(nèi)存。

            <!--[if !supportLists]-->3. <!--[endif]-->int mNumFaceGroups; int mFaceGroupStart;
            用來找到BspLevel中哪些face group是屬于我這個leaf的,這樣做也是為了優(yōu)化存儲;

            <!--[if !supportLists]-->4. <!--[endif]-->IntersectingObjectSet mMovables;
            和本節(jié)點相交的movable對象

            <!--[if !supportLists]-->5. <!--[endif]-->NodeBrushList mSolidBrushes;
            本節(jié)點包含的brush。

            另外剩下的OgreQuake3Level.h、OgreQuake3Shader.h、OgreQuake3ShaderManager.h、 OgreQuake3Type.h主要是為了把Quake3格式的bsp,shader信息讀入,并轉(zhuǎn)換成Ogre本地的bsp定義以及 Material。現(xiàn)在quake3的源碼已經(jīng)公開(非常感謝id software以及carmark),可以結(jié)合quake3的源碼來看。



            【2. Quake3 bsp的加載】
            以Demo_BSP為例,首先需要修改“quake3settings.cfg”,兩個參數(shù),“Pak0Location”是pk包的路徑(是一個zip文件),“Map”為想要加載的地圖。

            OGRE使用BspLevel來存儲Bsp場景信息,這個類是與文件格式無關(guān)的。所以需要另外一個類來把Quake3的bsp文件讀入。

            Quake3Level的讀盤的主要由兩個函數(shù)完成:

            1、“void Quake3Level::loadHeaderFromStream()”。調(diào)用的流程是:

            BspApplication::loadResources()

            à ResourceGroupManager::loadResourceGroup()【A】

            à BspSceneManager::estimateWorldGeometry()

            à BspLevel::calculateLoadingStages()

            àQuake3Level::loadHeaderFromStream()

            Quake3 BSP的文件格式很簡單明了,前面是一個文件頭,后面是幾個數(shù)據(jù)塊。文件頭主要存儲了幾個lump,包含數(shù)據(jù)塊的起始位置和大小,通過lump,可以直接seek到對于的數(shù)據(jù)塊。
            此函數(shù)在加載了文件頭之后,調(diào)用了Quake3Level:: initialiseCounts ()函數(shù),主要是計算了每個lump包含的對象的個數(shù),例如face,vertex,bursh等等。

            2、第二個函數(shù)“void Quake3Level::loadFromStream()”。調(diào)用的過程是:

            ResourceGroupManager::loadResourceGroup()【A】

            àBspSceneManager::setWorldGeometry()

            àBspResourceManager::load()

            àResourceManager::load()

            àResource::load()

            àBspLevel::loadImpl()

            àQuake3Level::loadFromStream()

            在這地方OGRE延續(xù)了他羅嗦的風(fēng)格,BspSceneManager要通過BspResourceManager來加載場景,BspLevel實現(xiàn)為一種 Resource,BspResourceManager通過標(biāo)準(zhǔn)的ResourceManager――》Resource來找到BspLevel,然后調(diào)用其加載函數(shù)。



            此函數(shù)首先構(gòu)造了一個“MemoryDataStream”對象,在 MemoryDataStream的構(gòu)造函數(shù)中把文件數(shù)據(jù)全部讀入其緩沖中(Quake也是這樣干的),然后調(diào)用“void Quake3Level::initialisePointers(void)”函數(shù),得到所有l(wèi)ump索引的對象的指針。



            Quake3Level 把文件讀入并明確了所有數(shù)據(jù)的指針之后,在void BspLevel::loadImpl()中調(diào)用“BspLevel::loadQuake3Level()”函數(shù)講Quake3level中的數(shù)據(jù)拷貝到自己的數(shù)據(jù)對象中。主要執(zhí)行了以下幾個操作:

            <!--[if !supportLists]-->1. <!--[endif]-->“BspLevel::loadEntities()”,這個lump存的是一個字符串,用來描述一些游戲信息,Ogre的這個函數(shù)只讀取了Player start信息(位置和角度)。

            <!--[if !supportLists]-->2. <!--[endif]-->“Quake3Level:: extractLightmaps()”。Quake3 BSP的每個light map都是128×128大,此函數(shù)將Light map lump中的數(shù)據(jù)逐個調(diào)用“TextureManager::loadImage()”創(chuàng)建成Texture對象(class D3D9Texture for D3D9 RenderSystem)。

            <!--[if !supportLists]-->3. <!--[endif]-->創(chuàng)建VertexData:
            [Create vertex declaration] OGRE BspLevel使用的頂點格式為:Position3,Normal3,Diffuse,uv0,uv1;
            [Build initial patches] 調(diào)用BspLevel::initQuake3Patches()。此函數(shù)遍歷Quake3Level中的所有faces,對于每個face type為“BSP_FACETYPE_PATCH”的face,創(chuàng)建一個PatchSurface對象,并調(diào)用PatchSurface:: defineSurface()函數(shù)進行,然后保存到BspLevel:: mPatches數(shù)組中。此函數(shù)還計算了BspLevel:: mPatchVertexCount和BspLevel:: mPatchIndexCount;
            [硬件頂點緩沖] 調(diào)用HardwareBufferManager創(chuàng)建HardwareVertexBuffer對象;使用“BspLevel:: quakeVertexToBspVertex()”函數(shù)把q3 bsp頂點格式轉(zhuǎn)換為Ogre BSPLevel的頂點格式。然后綁定到BspLevel::mVertexData;

            <!--[if !supportLists]-->4. <!--[endif]-->創(chuàng)建Faces:創(chuàng)建BspLevel:: mLeafFaceGroups數(shù)組;創(chuàng)建BspLevel:: mFaceGroups數(shù)組,此數(shù)組的數(shù)據(jù)在后面一步中填充;創(chuàng)建indexbuffer,并將Quake3Level::mElements拷貝進來;

            <!--[if !supportLists]-->5. <!--[endif]-->Create materials for shaders:對于Quake3Level::mFaces每一個bsp_face_t,找到它索引的Quake3Shader,并創(chuàng)建 Material,如果沒有找到Quake3Shader的話則使用shader name去查找貼圖文件;
            在此循環(huán)中還進行了“Copy face data”的操作,填充BspLevel:: mFaceGroups中的數(shù)據(jù);

            <!--[if !supportLists]-->6. <!--[endif]-->Nodes:創(chuàng)建BspLevel:: mRootNode數(shù)組,并將數(shù)據(jù)拷貝進來。

            <!--[if !supportLists]-->7. <!--[endif]-->Brushes:將數(shù)據(jù)拷貝到BspLevel:: mBrushes中;

            <!--[if !supportLists]-->8. <!--[endif]-->Leaves:設(shè)置每個leaf節(jié)點的數(shù)據(jù),主要包括包裹盒,mFaceGroupStart,mNumFaceGroups,mVisCluster,mSolidBrushes。參見BspNode類;

            <!--[if !supportLists]-->9. <!--[endif]-->Vis data:將數(shù)據(jù)拷貝到BspLevel:: mVisData中。

            Quake3 BSP的load流程基本上就是這些了。

            【3. Bsp tree scene的渲染】
            仍然以Demo_BSP為例來分析。渲染的核心操作流程從SceneManager::_renderScene()開始(參見“Ogre學(xué)習(xí)筆記(3):Mesh的渲染流程”),接下來還有SceneManager:: _updateSceneGraph(),SceneManager::prepareRenderQueue(),BspSceneManager沒有重寫這幾個函數(shù)。不過,有一點需要注意,SceneManager:: _updateSceneGraph()調(diào)用了BspSceneNode::_update()與OctreeSceneManager類似的,如果有必要的話,會調(diào)用BspSceneManager:: _notifyObjectMoved()--》BspLevel:: _notifyObjectMoved(),將SceneNode中的MovableObject attach到正確的leaf node中。
            接下來是BspSceneManager:: findVisibleObjects(),這是一個從SceneManager重寫的函數(shù)。順理成章的,這個函數(shù)調(diào)用了 BspSceneManager::walkTree()。在這個函數(shù)中,首先找到了camera所在的leaf node(通過BspLevel::findleaf()函數(shù));然后遍歷BspLevel中的每個leaf node,先使用PVS檢測可見性(通過BspLevel::isLeafVisible()函數(shù)),如果可見再使用camera――bounding box檢測,如果還是可見的,則對此leaf node調(diào)用BspSceneManager::processVisibleLeaf()函數(shù)。此函數(shù)主要執(zhí)行兩個操作,一個是把World Geometry加入到渲染數(shù)據(jù)表中(mFaceGroupSet和mMatFaceGroupMap),另外一個是把與此leaf node相交的MoveableObject加到渲染隊列中(mMovablesForRendering)。一件比較有疑問的事情是,walkTree 是循環(huán)遍歷所有l(wèi)eaf node,而沒有按照BSP tree遞歸遍歷,這大大削弱了BSP的提前排序的優(yōu)勢。

            然后是BspSceneManager重寫了另外一個重要的函數(shù)_renderVisibleObjects()。此函數(shù)包含兩個操作,一個是 renderStaticGeometry(),另外一個是調(diào)用父類的SceneManager::_renderVisibleObjects()。前者循環(huán)遍歷mMatFaceGroupMap,然后調(diào)用RenderSystem::_rendr();后者已經(jīng)在“Ogre學(xué)習(xí)筆記(3):Mesh的渲染流程”中詳細分析過了。



             
            posted on 2007-07-18 02:44 七星重劍 閱讀(917) 評論(0)  編輯 收藏 引用 所屬分類: Game EngineOGRE
            欧美va久久久噜噜噜久久| 国产韩国精品一区二区三区久久| 日韩亚洲欧美久久久www综合网 | 久久久久成人精品无码| 久久综合久久综合亚洲| 成人久久免费网站| 久久91精品综合国产首页| 久久久久亚洲国产| 青青青青久久精品国产| 久久精品中文无码资源站| 中文字幕成人精品久久不卡| 国产偷久久久精品专区| 久久久久国色AV免费观看| 人妻无码中文久久久久专区| 国产精品美女久久久久av爽| 色综合久久中文字幕无码| 色悠久久久久久久综合网| 伊人久久大香线蕉影院95| 日韩人妻无码一区二区三区久久| 国产女人aaa级久久久级| 国产午夜精品久久久久免费视| 精品久久久久久无码不卡| 久久久精品视频免费观看| 国产精品久久久久久吹潮| 亚洲av成人无码久久精品| 国产精品久久久久久久人人看| 久久久久婷婷| 国产精品无码久久四虎| 狠狠色丁香婷综合久久| 久久国产亚洲高清观看| 久久精品国产亚洲AV无码偷窥| 久久亚洲AV成人无码软件| 亚洲欧美久久久久9999| 色欲综合久久躁天天躁| 人妻系列无码专区久久五月天| 青青草原综合久久大伊人精品| 2021久久精品国产99国产精品| 国产精品久久久久久福利漫画 | 欧美成a人片免费看久久| 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲 | 久久久久久a亚洲欧洲aⅴ|