前段時(shí)間看了很多很多的3D相關(guān)的基礎(chǔ)書,感覺上學(xué)到了很多東西,但是不知道做什么好。后來,用DXUT做了兩個(gè)小游戲,連連看和紙牌,雖然都是2D的,但是感覺上還是覺得自己進(jìn)步了。
接下來的一段日子里,是時(shí)候繼續(xù)學(xué)3D的東西了,于是萌生了個(gè)做游戲引擎的想法。我是個(gè)想做就做的人,雖然我也知道自己是不自量力,但是,只要我肯去做,即使做不好,也起碼能學(xué)到東西啊,把學(xué)過的東西拿來用一番,就能有感覺了。
說說引擎部分的構(gòu)建,引擎部分的FrameWork主要參考了GPG3的1.2那個(gè)框架模式,采用Unicode編譯,感覺上那個(gè)模式比較好用,但是太復(fù)雜了點(diǎn),于是我簡化了他,基本上只保留了任務(wù)系統(tǒng)。使用平臺(tái)無關(guān)的插件方式把Win32和Direct3D9的模塊做了出來(當(dāng)然只封裝了一小部分函數(shù)),把Ogre的基礎(chǔ)庫全部拿來主義(哈哈,主要就是數(shù)學(xué)庫、工具庫等等)。而聲音引擎也留了接口,很好擴(kuò)展了。
然后,現(xiàn)在正在做GUI部分,主要還是說說GUI的渲染部分吧。GUI其中有兩個(gè)我認(rèn)為比較關(guān)鍵的地方,其一是渲染文字部分,其二是渲染窗口部分。下面說說我的做法
文字渲染部分:
我的做法是使用FreeType2讀取TTF文件,然后當(dāng)要渲染文字的時(shí)候,看哪個(gè)用到的文字就load哪個(gè)文字,先獲得這個(gè)文字的大小,然后在貼圖中找到一個(gè)空閑的區(qū)域(我的貼圖大小是512×512,也可以設(shè)置),然后blt到貼圖中,真正渲染的時(shí)候就把這個(gè)貼圖紋理坐標(biāo)貼到兩個(gè)三角形上就完成了一個(gè)文字的渲染了。
在貼圖中找空閑區(qū)域我有個(gè)比較特別的做法,就是每個(gè)需要渲染的文字維護(hù)一個(gè)RefCount引用計(jì)數(shù),例如一個(gè)屏幕里10個(gè)“我”字,那么“我”的引用計(jì)數(shù)就是10,當(dāng)“我”字不需要再渲染的時(shí)候(引用計(jì)數(shù)為0),此文字的貼圖區(qū)域就可以被其他文字所覆蓋。
窗口渲染部分:

class?GAMECORE_EXPORT?GUIRenderCache


{
protected:
????//?不允許顯式創(chuàng)建,只可以繼承
????GUIRenderCache(void);
public:
????virtual?~GUIRenderCache(void);

????//?添加到渲染隊(duì)列
????void?AddCache(const?GUIRenderQuad&?quad)

????
{
????????m_vtGUIRenderQuad.insert(GUIRenderQuadPtr(new?GUIRenderQuad(quad)));
????}


????//?渲染需要Cache隊(duì)列
????void?RenderCache(void)

????
{
????????//?從新Cache隊(duì)列
????????if(m_bDirty)

????????
{
????????????ClearCacheList();
????????????DoCache();
????????????m_bDirty?=?false;
????????}
????????//?添加到渲染器
????????for(VectorGUIRenderQuad::const_iterator?iter?=?m_vtGUIRenderQuad.begin()?;?iter?!=?m_vtGUIRenderQuad.end()?;?iter?++)

????????
{
????????????Systems::GetSingleton().GetGUIRendererSystem()->AddCache(*iter);
????????}
????}
????//?清空cache隊(duì)列
????void?ClearCacheList(void)

????
{
????????m_vtGUIRenderQuad.clear();
????}
protected:

????//?Cache需要渲染的項(xiàng)目

????virtual?void?DoCache()
{};

????VectorGUIRenderQuad?m_vtGUIRenderQuad;????//?渲染隊(duì)列
????bool?m_bDirty;?//?需要重新Cache需要渲染的項(xiàng)目
};

每個(gè)Window(一個(gè)Window是一個(gè)抽象類,Static/Button/Dialog等等所有窗口都是繼承于Window)都繼承于GUIRenderCache對象,當(dāng)窗口的某個(gè)屬性(如WindowText)改變時(shí),就會(huì)把m_bDirty標(biāo)記設(shè)置成true。每幀渲染的時(shí)候調(diào)用RenderCache。那么如果窗口的屬性沒有改變,就只需要把m_vtGUIRenderQuad的東西渲染出來;如果屬性改變了(即m_bDirty為true),則調(diào)用DoCache,由繼承類(如Static/Button等)改寫這個(gè)函數(shù),計(jì)算貼圖坐標(biāo)、三角形坐標(biāo)等等東西都放在這個(gè)函數(shù)里。總的來說,Cache之后速度會(huì)比Cache之前快起碼一半以上。
好了,睡覺去了。
接下來的一段日子里,是時(shí)候繼續(xù)學(xué)3D的東西了,于是萌生了個(gè)做游戲引擎的想法。我是個(gè)想做就做的人,雖然我也知道自己是不自量力,但是,只要我肯去做,即使做不好,也起碼能學(xué)到東西啊,把學(xué)過的東西拿來用一番,就能有感覺了。
說說引擎部分的構(gòu)建,引擎部分的FrameWork主要參考了GPG3的1.2那個(gè)框架模式,采用Unicode編譯,感覺上那個(gè)模式比較好用,但是太復(fù)雜了點(diǎn),于是我簡化了他,基本上只保留了任務(wù)系統(tǒng)。使用平臺(tái)無關(guān)的插件方式把Win32和Direct3D9的模塊做了出來(當(dāng)然只封裝了一小部分函數(shù)),把Ogre的基礎(chǔ)庫全部拿來主義(哈哈,主要就是數(shù)學(xué)庫、工具庫等等)。而聲音引擎也留了接口,很好擴(kuò)展了。
然后,現(xiàn)在正在做GUI部分,主要還是說說GUI的渲染部分吧。GUI其中有兩個(gè)我認(rèn)為比較關(guān)鍵的地方,其一是渲染文字部分,其二是渲染窗口部分。下面說說我的做法
文字渲染部分:
我的做法是使用FreeType2讀取TTF文件,然后當(dāng)要渲染文字的時(shí)候,看哪個(gè)用到的文字就load哪個(gè)文字,先獲得這個(gè)文字的大小,然后在貼圖中找到一個(gè)空閑的區(qū)域(我的貼圖大小是512×512,也可以設(shè)置),然后blt到貼圖中,真正渲染的時(shí)候就把這個(gè)貼圖紋理坐標(biāo)貼到兩個(gè)三角形上就完成了一個(gè)文字的渲染了。
在貼圖中找空閑區(qū)域我有個(gè)比較特別的做法,就是每個(gè)需要渲染的文字維護(hù)一個(gè)RefCount引用計(jì)數(shù),例如一個(gè)屏幕里10個(gè)“我”字,那么“我”的引用計(jì)數(shù)就是10,當(dāng)“我”字不需要再渲染的時(shí)候(引用計(jì)數(shù)為0),此文字的貼圖區(qū)域就可以被其他文字所覆蓋。
窗口渲染部分:




























































每個(gè)Window(一個(gè)Window是一個(gè)抽象類,Static/Button/Dialog等等所有窗口都是繼承于Window)都繼承于GUIRenderCache對象,當(dāng)窗口的某個(gè)屬性(如WindowText)改變時(shí),就會(huì)把m_bDirty標(biāo)記設(shè)置成true。每幀渲染的時(shí)候調(diào)用RenderCache。那么如果窗口的屬性沒有改變,就只需要把m_vtGUIRenderQuad的東西渲染出來;如果屬性改變了(即m_bDirty為true),則調(diào)用DoCache,由繼承類(如Static/Button等)改寫這個(gè)函數(shù),計(jì)算貼圖坐標(biāo)、三角形坐標(biāo)等等東西都放在這個(gè)函數(shù)里。總的來說,Cache之后速度會(huì)比Cache之前快起碼一半以上。
好了,睡覺去了。