• <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>

            游戲中的渲染器架構(gòu)

            這里的“游戲”我只討論一般的小游戲,這里的渲染器也特指游戲中負(fù)責(zé)所有(或者說(shuō)大部分)渲染工作的那個(gè)對(duì)象。而我這里說(shuō)所的“架構(gòu)”則是指如何安排這個(gè) “渲染器”與游戲中其他對(duì)象(類(lèi))的關(guān)系,之所以要討論這種關(guān)系,是因?yàn)楹芏鄷r(shí)候我們都需要改善游戲中邏輯部分和渲染部分之間的關(guān)系。如果這種關(guān)系藕荷度太高,最直接的問(wèn)題就是導(dǎo)致代碼可擴(kuò)展性不高。

            渲染代碼往往依賴(lài)于開(kāi)發(fā)所使用的開(kāi)發(fā)包。假使你直接使用DirectX或者OpenGL,你的渲染代碼很有可能會(huì)直接涉及到各種DirectX或OpenGL中的概念。在代碼級(jí)別,就是會(huì)牽扯進(jìn)很多跟開(kāi)發(fā)包相關(guān)的類(lèi),函數(shù),結(jié)構(gòu)體等等之類(lèi)。

            也許你會(huì)對(duì)DirectX或OpenGL做二次封裝,開(kāi)發(fā)出一些游戲引擎(或者只是單純的圖形引擎)。于是,現(xiàn)在的渲染代碼就可以只跟你的游戲引擎相關(guān)(代碼級(jí)別)。

            無(wú)論如何,如果直接使用DirectX或OpenGL(一次封裝都沒(méi)做這是很爛的方式),當(dāng)你移植游戲時(shí)你很有可能就會(huì)面臨從DirectX到 OpenGL代碼轉(zhuǎn)化的問(wèn)題(反之亦然)。而使用游戲引擎呢?游戲引擎隔離了底層具體的開(kāi)發(fā)包(DirectX或OpenGL),但是如果要換引擎呢?換引擎這樣的情況我認(rèn)為是完全存在的,例如現(xiàn)在在Windows下開(kāi)發(fā)了一個(gè)基于HGE的游戲,現(xiàn)在我想把這個(gè)游戲移植到Linux 下。而HGE是基于DirectX的,要移植到Linux下,你當(dāng)然可以保持HGE的接口不變,而使用OpenGL重寫(xiě)HGE。這里,你就需要重新開(kāi)發(fā)一個(gè)引擎!這很浪費(fèi)時(shí)間!所以你可能會(huì)使用另一個(gè)在Linux 下運(yùn)行的引擎(跨平臺(tái)的引擎也可以),例如ClanLib,于是,這里就涉及到了“換引擎”的問(wèn)題。

            從上文我們可以看出,基于很多原因(不僅僅是要把代碼做移植,好的架構(gòu)還利于代碼的擴(kuò)展,利于開(kāi)發(fā)過(guò)程---特指編碼過(guò)程----的平穩(wěn)進(jìn)行等等之類(lèi)),游戲中渲染器的架構(gòu)需要得到關(guān)注。



            接下來(lái)我將討論幾種不同的架構(gòu):

            一.這也是最爛的方式,游戲中無(wú)論在什么地方,只要需要渲染了,就加渲染代碼。其結(jié)果就是各種與圖形開(kāi)發(fā)包相關(guān)的東西鋪天蓋地。這樣的代碼根本沒(méi)任何幽雅性可討論。事實(shí)上,在很多游戲開(kāi)發(fā)相關(guān)的書(shū)籍中早就提到過(guò)類(lèi)似“將游戲邏輯和渲染分離開(kāi)來(lái)”的觀點(diǎn)。



            二.這是我使用了很多次的架構(gòu)方式,類(lèi)圖為:



            Game類(lèi)是一個(gè)Manager類(lèi),Renderer類(lèi)里包含了游戲中所有的渲染代碼,Monster是一個(gè)具體的怪物類(lèi),它沒(méi)有類(lèi)似于Render或者 Draw之類(lèi)的接口,這些接口都被放在Renderer類(lèi)里,例如RenderMonster()。當(dāng)游戲需要渲染這個(gè)Monster對(duì)象時(shí),Game對(duì)象就調(diào)用Renderer類(lèi)的RenderMonster接口。

            于是,現(xiàn)在Monster類(lèi)里(基于這種架構(gòu),其他所有的精靈類(lèi)以及各種需要渲染的非精靈類(lèi))就沒(méi)有任何與圖形開(kāi)發(fā)包相關(guān)的東西。而與圖形開(kāi)發(fā)包相關(guān)的東西則都集中到了Renderer類(lèi)里。當(dāng)你要移植代碼時(shí),只需要重寫(xiě)Renderer類(lèi)即可。

            但是這種架構(gòu)還是有很多問(wèn)題:

            1.隨著游戲越做越大,游戲中需要得到渲染的物體就會(huì)越來(lái)越多。這樣,每次都給Renderer類(lèi)添加一個(gè)RenderSomething之類(lèi)的接口(注意,除了添加接口外很有可能還要添加一些渲染所需要的對(duì)象,例如Surface之類(lèi)的)。Renderer類(lèi)最終將成為一個(gè)非常巨大的類(lèi),這違背了面向?qū)ο笤O(shè)計(jì)的原則(巨類(lèi)導(dǎo)致的最直接的壞處就是改代碼痛苦-----鼠標(biāo)滾輪滾半天才找到目標(biāo)代碼。just a joke。)

            2.事實(shí)上,Renderer類(lèi)的RenderSomething 之類(lèi)的接口在被調(diào)用時(shí)還需要一些渲染參數(shù)。例如渲染一個(gè)精靈類(lèi)的話,就需要知道要渲染哪一幀,以及渲染到哪里之類(lèi)的信息。在某些時(shí)候,這些參數(shù)會(huì)讓這些接口的declaration 變的很惡心!(代碼要幽雅,先把格式寫(xiě)好看點(diǎn)------當(dāng)然你愿意去參加“混亂代碼大賽”的話倒可以朝這個(gè)方向發(fā)展,another joke)



            三.我始終記得一句關(guān)于面向?qū)ο笤O(shè)計(jì)的話:“面向?qū)ο笫怯脕?lái)模擬世界的”(大致是這樣的)。這句話其實(shí)真的可以作為面向?qū)ο箝_(kāi)發(fā)的一個(gè)指導(dǎo)性原則,它會(huì)讓你在架構(gòu)系統(tǒng)時(shí)變得很容易。因此,套用這句話的話,上面那種架構(gòu)方式就出現(xiàn)一些讓人覺(jué)得別扭的地方了。怪物對(duì)象為什么不能自己渲染自己?(難道一個(gè)人表現(xiàn)自己的能力都沒(méi)有?爛比喻!)按照那條原則,怪物類(lèi)理所應(yīng)該擁有一個(gè)Render之類(lèi)的接口!

            于是,架構(gòu)二稍微做了些變化:



            我們讓每個(gè)需要渲染的物體,這里是Monster,都有一個(gè)Render接口以及一個(gè)Renderer對(duì)象指針。在創(chuàng)建該精靈對(duì)象時(shí),Game類(lèi)把自己創(chuàng)建的Renderer對(duì)象指針傳給該精靈對(duì)象。該精靈對(duì)象再保存該指針到mRender成員。當(dāng)渲染時(shí),Game類(lèi)不再直接調(diào)用Renderer對(duì)象里的 RenderSomething之類(lèi)的接口,而是很自然地調(diào)用Monster的Render接口。然后Monster的Render接口再通過(guò)自己保存的 Renderer對(duì)象指針調(diào)用其RenderMonster接口。

            這里,我們?yōu)榱俗屧O(shè)計(jì)更貼近真實(shí)世界,就多加了一條依賴(lài)關(guān)系。(這其實(shí)純碎是某些完美主義程序員的癖好-----for instance, me :D)

            四.這可能是種被普遍使用的方式:

            類(lèi)圖為:


            這里不再有Renderer類(lèi)了,精靈也不再象方式三中的那種“虛假”的Render了。取而代之的是,精靈類(lèi)(以及其他需要渲染對(duì)象)自己直接使用圖形引擎來(lái)渲染自己,自己也保存渲染所需要的信息,例如那個(gè)mImage。

            這種方式的缺點(diǎn)在于:每個(gè)需要渲染的物體就都會(huì)與圖形開(kāi)發(fā)包相關(guān)。當(dāng)然如果代碼組織得當(dāng),在移植時(shí)也不是很費(fèi)勁。但是它造成了代碼層次上的相關(guān)性,讓我覺(jué)得不是很好。(代碼相關(guān)性:例如要涉及到圖形引擎的類(lèi)(例如Image ),還要包含一些圖形引擎頭文件,這樣一折騰就讓我覺(jué)得很不爽)





            總結(jié)了以上四種方式,我在這里試著提出一種個(gè)人覺(jué)得更為好的架構(gòu)方式(因?yàn)檫€沒(méi)在實(shí)際的項(xiàng)目中實(shí)驗(yàn)過(guò),所以只能說(shuō)“試著”)。

            關(guān)于渲染所需要的渲染信息,其最基本的信息就是類(lèi)似于Surface,Image之類(lèi)的用來(lái)代表該物體外觀圖片的對(duì)象。又由于圖片資源的一些屬性,很有可能還會(huì)涉及到一些輔助加工資源的變量(例如對(duì)于一個(gè)精靈,某一幀對(duì)應(yīng)于圖片上的矩形區(qū)域)。

            這里涉及的問(wèn)題就變?yōu)椋阂粋€(gè)需要被渲染的物體,除了其渲染代碼與特定的圖形開(kāi)發(fā)包相關(guān)外,其渲染信息數(shù)據(jù)也與圖形開(kāi)發(fā)包相關(guān)。如何盡可能地把這些代碼與邏輯部分代碼分離?

            于是我得到了如下的架構(gòu)形式:



            每一個(gè)需要渲染的物體都擁有一個(gè)其自己的渲染器,然后每個(gè)特定的渲染器還有一個(gè)其特有的資源管理器(這里主要管理圖片資源-----事實(shí)上只是作為一種資源加工器而已)。

            這種方式其實(shí)就是上面提到的方式二的改進(jìn)版本,把方式二中的那個(gè)巨類(lèi)分割開(kāi)來(lái)。而為了更方便地進(jìn)行渲染,Monster在創(chuàng)建MonsterRenderer對(duì)象時(shí)可以把自身作為參數(shù)傳給MonsterRenderer并讓其保存。這樣,又多了條依賴(lài)關(guān)系:



            有時(shí)候,對(duì)于一個(gè)精靈而言,為了靈活地配置其部分屬性(這部分屬性如果硬編碼的話很有可能就是一些常量或者宏),我們還要為精靈增加一個(gè)屬性讀取器,它會(huì)從外部配置文件讀入屬性-----事實(shí)上這不是本文討論的范圍-----例如使用一種XML解析庫(kù)來(lái)從XML配置文件中讀取數(shù)據(jù),可以這樣設(shè)計(jì):


            如果精靈渲染信息數(shù)據(jù)也需要由外部文件配置,并且與那些屬性被放在同一個(gè)配置文件中(這可能不是種好的習(xí)慣),這樣,PropertiesReader和MonsterResMgr就會(huì)從同一個(gè)XML配置文件中讀取數(shù)據(jù)。我們可以這樣解決這個(gè)問(wèn)題:


            所有配置數(shù)據(jù)都由PropertiesReader讀取,Monster負(fù)責(zé)創(chuàng)建PropertiesReader對(duì)象,然后把該對(duì)象指針傳給 MonsterRenderer對(duì)象。事實(shí)上,因?yàn)镸onsterRenderer對(duì)象保存有Monster對(duì)象指針,所以完全可以訪問(wèn)到 PropertiesReader對(duì)象

            posted on 2010-12-28 21:52 裴孝剛 閱讀(466) 評(píng)論(1)  編輯 收藏 引用 所屬分類(lèi): 網(wǎng)上轉(zhuǎn)載

            評(píng)論

            # re: 游戲中的渲染器架構(gòu) 2011-01-17 19:11 煙圈

            厲害。。很不錯(cuò)啊。。  回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            <2011年1月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(1)

            隨筆分類(lèi)

            隨筆檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            国内精品久久久久影院优| 久久久中文字幕日本| 一本色道久久88—综合亚洲精品| 综合久久精品色| 久久精品国产亚洲av麻豆色欲| A级毛片无码久久精品免费| 国产精品一区二区久久精品无码| 一本色综合久久| 99久久精品国产麻豆| 久久午夜无码鲁丝片午夜精品| 欧美精品久久久久久久自慰| 色综合久久最新中文字幕| 伊人 久久 精品| 99久久国产综合精品五月天喷水 | 久久精品毛片免费观看| 久久99精品国产99久久6| 中文字幕日本人妻久久久免费 | 日韩美女18网站久久精品| 亚洲国产欧洲综合997久久| 国内精品久久久久影院网站| 久久精品aⅴ无码中文字字幕不卡| 国产精品久久久久久搜索| 中文字幕久久波多野结衣av| 久久99精品国产99久久6| 久久99精品国产麻豆宅宅 | 91久久精品无码一区二区毛片| 77777亚洲午夜久久多喷| 中文成人无码精品久久久不卡 | 97久久香蕉国产线看观看| 国产免费久久精品99re丫y| 久久无码精品一区二区三区| 免费观看久久精彩视频| …久久精品99久久香蕉国产| 久久超碰97人人做人人爱| 久久九九兔免费精品6| 亚洲精品综合久久| 日韩美女18网站久久精品| 亚洲欧美日韩久久精品| 色天使久久综合网天天| 日本久久中文字幕| 久久人人爽人人爽人人片AV高清|