盖莫游戏引擎是我设计的一个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)