轉載自:http://www.lihuasoft.net/article/show.php?id=4853
寫了幾個月的遊戲引擎,有一些想法需要總結結一下,也想和同我水準差不多的朋友,或者比我水準還要菜的cn們分享一下,高手莫笑~~
這裡的想法是,盡量和大家分享我的過程,我寫的東西很爛(我的确這樣覺得),我會在文中寫下來我覺得還存在問題的地方,需要改進的地方,或者還沒有想到很好解決的地方;希望同大家互相讨論,也非常歡迎高手們的建議和批評.Just for FUN! OK. (ps:文中的代碼都是片斷,these don’t compile,如果你想要部分代碼,可以和我聯系,在引擎完成得差不多的時候我會郵給你,我的郵箱: [email protected] or [email protected] . ) 目标是寫一個多渲染器的遊戲引擎,先來談其中的圖形渲染部分,畢竟這個是關鍵,如果你想了解實體,網絡或者其他的内容,很遺憾,這裡沒有(也許要等到很後面的了)。可以看一下我之前寫的兩篇blog,《遊戲引擎中多渲染器的設計與實作》(1,2),裡面講到了用動态連結庫實作的一種的方法,這裡就不複習了,假設你已經完成了前面最基本的實作。
引擎的核心部分是一切的前提,是以我們從這裡開始。我強烈建議你在開始動手之前先看一下常用的3d模型的格式的解析——因為引擎的底層的基本資料類型的設計是非常重要,而且在後面是相當難以改動的——看一下常用的模型格式的解析,可以幫助你設計合理的底層資料類型(這裡指的是像紋理,材質,三角形等的表示)。先以MilkShape 3D的格式MS3D為例。在他們的網站上,你可以下到一個C++解析元件,先看頭檔案中的資料類型:
從代碼中可以看出,Texture和Material都有name,都有fileName(指的是貼圖檔案名),Material中有4中顔色(這和圖形學裡面的實體意義也是一緻的),然後就是Texture可以是alpha貼圖,有屬性transparency,這些都可以作為我們設計的參考。我們就停在這裡,在後面我們還會看到這個經典的格式是怎樣影響了我們的渲染批次的設計的。
開始建立基礎的資料類型:
這裡很奇怪的是,我在Texture裡面用了一個void*。恩,這個是用來存儲不同API中的紋理。比如,如果是用的DX,我會一直把這個 void*看成LPDIRECT3DTEXTURE9*。在引擎中,我會大量的用到指針間的靜态轉換(非運作時)(hard core c++高手看到我的代碼會說應該用static_cast,而不是用c語言裡面的(typename)(…)。恩,我同意,隻是有時候我忘了,或者懶了)。
有很多的引擎,會将Texture單獨的抽象成一個類,有相應的行為(成員函數);但是,我覺得,Texture的實質是一堆資料,既然Texture Manager(紋理管理器,簡記為TextureMng)是必要的,那麼單獨的Texture的類的設計似乎沒有太多的必要,我們有TextureMng的管理,這樣似乎足夠了,我暫時不想把事情搞得太複雜。 (ps:面對對象是很好的方法,但是引擎中的很多“東西”的實質還是資料的集合,在把他們變成類之前,考慮一下于他們相關的操作,考慮一下用類實作一些很小的資料體的時候效率的影響。。。像Quake3和Ogre就是兩個設計的極端,是不是有時候結合兩者會好一些?)
還有很多的資料類型要寫,比如很多的3D中的數學類,像Vector3,Matrix4,先把他們放一下。我比較喜歡疊代開發的感覺——用比較短的周期,作出簡單的可運作的程式,然後在改進。好,我們就以dx sdk裡面的例子開始,先實作一個Vertex的例子。
我們需要定義一個VertexBuffer的抽象類,來給GL和DX提供公共的接口。 (ps:多渲染器引擎中,用抽象類(純虛類)是一種實作中的設計,即使用不同的API的底層實作,對于使用者來說,都是同一接口)
在DX9渲染器中我們加入檔案,UHEDX9VertexBuffer.h和UHEDX9VertexBuffer.cpp。 在UHEDX9VertexBuffer.cpp中,完成這些實作(看一下dx sdk,沒有什麼值得多說的了) 先寫到這裡,明天繼續。。。