蓋莫游戲引擎是我設計的一個2/3d游戲引擎,已經做了1年多了。
出于各種考慮我都需要對其進行大規模的改寫,以便在框架上具有良好清晰的架構(當然也會不斷新加入很多功能)。在參考了irr和其他幾個引擎代碼之后,我把引擎的場景繼承關系設計為:
Object->Transform->SceneNode這樣的關系
Object是一般的對象基類
Transform是控制世界矩陣和局部矩陣的類對象
其代碼如下:
1 ///////////////////////////////////////////////////////
2 /// 用4*4矩陣來定義3d世界物體的位置和角度,并生產一個樹狀繼承
3 ///////////////////////////////////////////////////////
4 class G_DLL_API Transform : public Object
5 {
6 public:
7 typedef std::vector<RefPtr<Transform> > ChildrenList;
8 typedef std::vector<RefPtr<Transform> >::iterator ChildrenItr;
9 public:
10 ///////////////////////////////////////////////////////
11 /// 構造,析構變換類
12 ///////////////////////////////////////////////////////
13 inline Transform(): parent(NULL),world_matrix_is_identity(false){}
14 Transform(const Matrix4f& matrix): parent(NULL), world_matrix_is_identity(false){SetLocalMatrix(matrix);}
15 virtual ~Transform(){}
16
17 ///////////////////////////////////////////////////////
18 /// 增加子節點
19 ///////////////////////////////////////////////////////
20 void AddChild(RefPtr<Transform> child);
21
22 ///////////////////////////////////////////////////////
23 /// 設置子節點
24 ///////////////////////////////////////////////////////
25 void SetChild(int index, RefPtr<Transform> child);
26
27 ///////////////////////////////////////////////////////
28 /// 獲取子節點個數
29 ///////////////////////////////////////////////////////
30 inline uint GetChildCount() const{return children.size();}
31
32 ///////////////////////////////////////////////////////
33 /// 獲取指定索引的子節點
34 ///////////////////////////////////////////////////////
35 inline RefPtr<Transform> GetChild(int i);
36 inline RefPtr<Transform> GetLastChild();
37
38 ///////////////////////////////////////////////////////
39 /// 節點移除
40 ///////////////////////////////////////////////////////
41 void EraseChild(RefPtr<Transform> child);
42 void EraseChildren(int index, int count);
43 void EraseAllChildren();
44 void EraseAllChildrenRecursive();
45
46 RefPtr<Transform> parent;
47
48 ///////////////////////////////////////////////////////
49 /// 獲取變換的4*4矩陣
50 ///////////////////////////////////////////////////////
51 inline Matrix4f GetComputedWorldMatrix();
52
53 ///////////////////////////////////////////////////////
54 /// 設置,獲取局部矩陣
55 ///////////////////////////////////////////////////////
56 void SetLocalMatrix(const Matrix4f& matrix){world_matrix = matrix;}
57 Matrix4f GetLocalMatrix(){return local_matrix;}
58
59 ///////////////////////////////////////////////////////
60 /// 平移,縮放,旋轉
61 ///////////////////////////////////////////////////////
62 void Translate(float x, float y, float z);
63 void Translate(const Vector3f& p);
64 void Scale(float x, float y, float z);
65 void Rotate(float degrees, float x, float y, float z);
66
67 ///////////////////////////////////////////////////////
68 /// 重新計算矩陣
69 ///////////////////////////////////////////////////////
70 virtual void ComputeWorldMatrix(RefPtr<Camera> camera);
71 void ComputeWorldMatrixRecursive(RefPtr<Camera> camera);
72 inline Matrix4f GetWorldMatrix(){return world_matrix;}
73
74 ///////////////////////////////////////////////////////
75 /// 設置,獲取是否保持單位世界矩陣
76 ///////////////////////////////////////////////////////
77 inline void SetAlwaysIdentityWorldMatrix(bool i){ world_matrix_is_identity = i; }
78 inline bool IsAlwaysIdentityWorldMatrix(){ return world_matrix_is_identity; }
79
80 protected:
81 ///////////////////////////////////////////////////////
82 /// 設置世界矩陣
83 ///////////////////////////////////////////////////////
84 void SetWorldMatrix(const Matrix4f& matrix){world_matrix = matrix;}
85 Matrix4f world_matrix;
86 Matrix4f local_matrix;
87 ChildrenList children;
88 bool world_matrix_is_identity;
89 };
然后是基本的場景節點類SceneNode
1 //! 2010.02.06
2 #ifndef SCENENODE_HPP
3 #define SNENENODE_HPP
4
5 ///////////////////////////////////////////////////////
6 /// 頭文件包含
7 ///////////////////////////////////////////////////////
8 #include <GEngine/Config.hpp>
9 #include <GEngine/Geometry.hpp>
10 #include <GEngine/Transform.hpp>
11
12 namespace core
13 {
14
15 ///////////////////////////////////////////////////////
16 /// 定義引擎基本場景節點類
17 ///////////////////////////////////////////////////////
18 class G_DLL_API SceneNode : public Transform
19 {
20 public:
21 ///////////////////////////////////////////////////////
22 /// 構造,析構場景節點
23 ///////////////////////////////////////////////////////
24 SceneNode();
25 virtual ~SceneNode();
26
27 public:
28 ///////////////////////////////////////////////////////
29 /// 獲取場景aabb盒子,球
30 ///////////////////////////////////////////////////////
31 Box GetSceneBox();
32 Spheref GetSceneSphere();
33
34 ///////////////////////////////////////////////////////
35 /// 場景渲染
36 ///////////////////////////////////////////////////////
37 void BeginRender();
38 void Render();
39 void RenderAfter();
40
41 ///////////////////////////////////////////////////////
42 /// 設置,獲取是否渲染(顯示)場景
43 ///////////////////////////////////////////////////////
44 void SetVisible(bool visible);
45 void EnableVisible();
46 void DisableVisible();
47 bool IsVisible()const;
48
49 ///////////////////////////////////////////////////////
50 /// 設置,獲取是否自動調用視錐體剔除
51 ///////////////////////////////////////////////////////
52 void SetAutoCulling(bool auto_cull);
53 bool IsAutoCulling()const;
54
55 protected:
56 ///////////////////////////////////////////////////////
57 /// 設置場景球,盒子
58 ///////////////////////////////////////////////////////
59 void SetSceneBox(const Box &box);
60 void SetSceneSphere(const Spheref &sphere);
61
62 ///////////////////////////////////////////////////////
63 /// 重新計算場景box,shpere
64 ///////////////////////////////////////////////////////
65 void UpdateBox();
66 void UpdateSphere();
67
68 bool visible;
69 bool auto_culling;
70 Spheref spheref;
71 Box box;
72 bool dirty_sphere;
73 bool dirty_box;
74 };
75
76 }
77
78 #endif
場景節點類在Transform的基礎之上增加了是否顯示,是否設置為自動調用視椎體剔除的函數
當然還有一般的虛擬場景渲染函數(3個)
當然這只是最基本的功能
( virtual void BeginRender();
virtual void Render();
virtual void RenderAfter();)
然后可以在SceneNode的基礎之上增加新的場景類型(比如:BillBoard等等)
題注:其實在引擎設計過程中我一直想避免這種復雜的繼承關系,但是之后我會發現當引擎功能越來越大的時候,不采用這種方式,引擎邏輯關系會變得越來越糟
我在想之后就可以加入一個場景渲染隊列來渲染場景了.
如果對游戲引擎設計感興趣 我們可以交流探討下(
ccsdu2009@sohu.com)