1. 程式人生 > >irrlicht原始碼總結(二)

irrlicht原始碼總結(二)

    好久沒寫文章了,這幾天又突發興趣來了解下原始碼。

    既然irrlicht幾乎能支援跨平臺和各個版本的c++(當然我的vs2017似乎不修改一些原始碼就不行了,因為原始碼好像用的還是directx9,個人覺得在如今GPU普及的時代,在怎麼也要支援到directx11才行吧。。。),好了,不說偏了。這就是為什麼irrlicht沒有使用c++標準庫裡的stl的原因,而是自己實現了一個stl,(當然還多了向量,矩陣等)。當然也就談不上廣泛利用c++11以上的特性了。

    所有的檔案在資料夾core中,看過標準stl原始碼的同志會發現,這裡的stl其實還是和標準庫差了個檔次的(所以還是建議各位能用標準庫就用標準庫吧),但架構大致還是類似的。

    首先必須看irrAllocator.h檔案,所謂allocator其實就是個類似於記憶體管理的東西,(所以你可以通過寫不同的allocator來實現不同的記憶體分配策略),眾所周知,比如一個class我每個物件new 100次 和 new 1次100個物件,效率是很明顯後者會提高很多的,並且前者可能記憶體不連續還會有碎片問題。而一個大型遊戲一個類有很多物件,所以可以在載入遊戲時就把可能要用的物件創造出來,結束時再銷燬。當然,讀者去看時就會發現這個allocator很簡單,只是把new和delete薄薄封起來而已,達不到什麼效果。有能力的人可以模仿stl自己寫allocator試試。(這個水還是挺深的,我當年也是研究了allocator很久)

    irrlicht似乎沒有提供stl裡的vector,這裡的vector2d和vector3d其實是固定大小的向量,提供了向量的各種運算。矩陣是matrix4,利用template可以使用各種型別。其實就是一些簡單的數學而已,比如說,平面的元素為(T可以替代為float,int等):

        vector3d<T> Normal;//! Normal vector of the plane.         T D;//! Distance from origin.

也就一個法向量和距離可以表示一個平面咯,

那麼什麼是點呢?,看點就是這樣的,點可以用向量表示:

#define position2d vector2d(利用c++11的using也可以達到相同的目的)

還有一個尺寸dimension(似乎該翻譯成這樣),看其元素,就兩個

            //! Width of the dimension.             T Width;             //! Height of the dimension.             T Height

這不就是高寬麼?,其實也可以用二維陣列vector2d<T>表示咯,殊途同歸。再看三角形的定義:

        //! the three points of the triangle         vector3d<T> pointA;         vector3d<T> pointB;         vector3d<T> pointC;

用的三個點而已,再看矩形

        //! Upper left corner         position2d<T> UpperLeftCorner;         //! Lower right corner         position2d<T> LowerRightCorner;

這當然是一個2d矩形咯

所謂quaternion四元數,應該很常見咯,這裡只有浮點數:

        f32 X; // vectorial (imaginary) part         f32 Y;         f32 Z;         f32 W; // real part

f32不用想,肯定就是float

(你去搜肯定能找到typedef float f32;)

直線line我就不列出了,肯定是兩個點表示的咯

當然有一個irrString(這個我不如char或wchar_t吧。。。)

irrMath裡提供了一部分數學函式,(我還是用cmath吧。。)

還有一顆RBTree,紅黑樹,也有相應的迭代器,但irr沒有type traits型別萃取就少了點味道啊,c++標準庫裡的set和map肯定是紅黑樹實現的,我相信讀者運用c++和標準庫,也可以寫出更優雅的紅黑樹。(或者把map裡的紅黑樹,我的vs裡是xtree)

裡面有一個heapsort堆排序,敘述這些的書都很多啦,至於coreutil,這個很簡單,程式碼也很少,似乎是用來查詢檔名字的(比如一個檔案是否在資料夾中),各位用fstream和string也能很輕鬆達到相同的目的。

還有list忘了,裡面的定義是

    struct SKListNode     {         SKListNode(const T& e) : Next(0), Prev(0), Element(e) {}

        SKListNode* Next;         SKListNode* Prev;         T Element;     };

很明顯是個雙向連結串列咯,因為構造的時候0個元素,那可能就不是環狀了(這個隨意了),這個list當然不及stl list了;

再看array,我似乎猜到這個array應該就如同vector了吧,裡面似有個新概念Alloc Strategy,難道是記憶體分配策略?噢,讀了一些程式碼發現它其實就是在模擬c++11的move功能,當然不如vector有那麼優秀的效率咯。

還有個叫aabbox3d,是由兩個點定義的

        //! The near edge         vector3d<T> MinEdge;

        //! The far edge         vector3d<T> MaxEdge;

這個是用於碰撞檢測的,實際遊戲中的物體不可能做那麼多碰撞檢測,就會轉化為一些簡單的幾何體當它的碰撞體積,當然,對於精度高的,可以用著名的BSP演算法來實現。

    想學習遊戲引擎原始碼的,建議大家把最新的原始碼下載看,在巨人的肩膀上學習,也能事半功倍。

    因為我只是幫各位梳理下思路,我跳過了其它很多細節,以上若有沒有聽過的概念(其實敘述那些的書很多了),還請各位自行查詢資料學習;若有我不當之處,嘿嘿,還請批評指正,謝謝。

    最後想談談未來的遊戲架構,遊戲引擎中各種功能可用軟體模擬,也可用硬體實現,大家看到的程式碼其實都是基於軟體模擬,毫無疑問,如果硬體直接支援能獲得數千倍不止的提升。

    想當年為解決cpu浮點運算,推出了fcpu,為解決3d遊戲的渲染問題,推出了gpu。那麼以後會不會為ai的神經元計算而普及ai cpu,會不會為真實的碰撞模擬推出collision cpu?我相信是可能的,因為我準備讀完研究生就去研究這些晶片,嘿嘿。