OGRE分析之场景管理

Mythma
http://www.cppblog.com/mythma
Email: mythma@163.com
一、场景的组成
antsam在《Ogre场景组织分析》中比喻场景的组织:“场景组织就像一个舞台,需要摄影机、灯光、服饰、道具和演员”,在这里我也借用一下。场景大概有如下几部分组成:
cameras ——〉摄影机
lights ——〉灯光
materials ——〉服装,不仅仅是演员的
entities ——〉演员
world geometry——〉房屋、地形等静态的场景
billboard
particle system
……
总体上来看,场景中的objects可分为可动实体和不可动实体。其中,Entities、Cameras和lights属于movable objects,World geometry属于immovable objects。materials依附于别的objects之上,无所谓动与不动。
OGRE把离散的,相对较小的,可移动的物体定义为Ogre::MovableObject
第 1 页 共 7 页
OGRE 分析之场景管理------Mythma
Camera属于Frustum的子类:
从另一个角度看,物体有可渲染和不可渲染之分。OGRE中能被渲染的Objects都属于Ogre::Renderable类:
比较MovableObject和Renderable可以发现,我们的“主角”Entity属于
第 2 页 共 7 页
OGRE 分析之场景管理------Mythma
MovableObject但却不属于Renderable:
Entity是不可渲染的?那肯定不对。在Renderable有一个SubEntity的子类,而Entity是由SubEntity组成的: typedef std::vector<SubEntity*> SubEntityList; SubEntityList mSubEntityList;
由此可以断定,Entity是被分解为SubEntity完成渲染的。
二、场景的管理
1、Ogre::SceneManager
OGRE的“场景管理员”是Ogre::SceneManager。该类负责组织场景中的物体,并负责把物体发送到渲染系统进行渲染。SceneManager本身是个虚基类,具体的实现由子类实现。
SceneManager的数据成员较多,对于上述Objects,基本上都用一个List来管理。另外,Camera, Light, SceneNode, Entity, BillboardSet, Animation, AnimationState, StaticGeometry等创建都是通过SceneManager实现的,并且创建后直接放入相应的List。
2、渲染队列
物体创建后,并不意味着就需要渲染在屏幕上。OGRE把需要渲染的Objects放入一个渲染队列中——Ogre::RenderQueue。
1) RenderQueue的组成
RenderQueue由Ogre::RenderQueueGroup组成的(名字上好像有点别扭),RenderQueue中有一个RenderQueueGroup的Map的数据成员: typedef std::map< RenderQueueGroupID, RenderQueueGroup * > RenderQueueGroupMap typedef MapIterator< RenderQueueGroupMap > QueueGroupIterator RenderQueueGroupMap mGroups
可见RenderQueueGroupMap 的key为RenderQueueGroupID,代表Objects的渲染先后顺序。RenderQueueGroupID是一个枚举量,根据场景内物体的
第 3 页 共 7 页
OGRE 分析之场景管理------Mythma
渲染顺序由先及后定义,如RENDER_QUEUE_BACKGROUND 为0,RENDER_QUEUE_OVERLAY 为100。
RenderQueue通过成员addRenderable 添加物体到渲染队列中:
void RenderQueue::addRenderable(Renderable* pRend,
RenderQueueGroupID groupID, ushort priority) { RenderQueueGroup* pGroup = getQueueGroup(groupID); // tell material it's been used pRend->getMaterial()->touch(); pGroup->addRenderable(pRend, priority); }
在RenderQueue的 getQueueGroup成员负责RenderQueueGroup的查找创建。RenderQueueGroup的生命周期由RenderQueue来控制。
2) RenderQueueGroup的组成
RenderQueueGroup中有一个RenderPriorityGroup的Map的数据成员: typedef std::map<ushort, RenderPriorityGroup*, std::less<ushort> > PriorityMap; typedef MapIterator<PriorityMap> PriorityMapIterator; PriorityMap mPriorityGroups;
PriorityMap的key为一个ushort,它代表着RenderPriorityGroup渲染的优先级。对同一优先级的Objects,RenderQueueGroup会通过成员函数addRenderable 将它加入相同的RenderPriorityGroup中: void RenderQueueGroup::addRenderable(Renderable* pRend, ushort priority) { // Check if priority group is there PriorityMap::iterator i = mPriorityGroups.find(priority); RenderPriorityGroup* pPriorityGrp; if (i == mPriorityGroups.end()) { // Missing, create pPriorityGrp = new RenderPriorityGroup(this, mSplitPassesByLightingType, mSplitNoShadowPasses); mPriorityGroups.insert(PriorityMap::value_type(priority, pPriorityGrp)); } else { pPriorityGrp = i->second; } // Add pPriorityGrp->addRenderable(pRend); }
从上面代码可以看出,RenderPriorityGroup的生命周期是由
第 4 页 共 7 页
OGRE 分析之场景管理------Mythma
RenderQueueGroup管理的。
3) RenderPriorityGroup的组成
RenderPriorityGroup中是存放需要渲染的Objects的最终场所。需要渲染的Objects——Renderable,RenderPriorityGroup组织将其组织为RenderableList,然后把RenderableList组织成SolidRenderablePassMap: typedef std::vector<Renderable*> RenderableList; typedef std::map<Pass*, RenderableList*, SolidQueueItemLess> SolidRenderablePassMap; SolidRenderablePassMap mSolidPasses; SolidRenderablePassMap mSolidPassesDiffuseSpecular; SolidRenderablePassMap mSolidPassesDecal; SolidRenderablePassMap mSolidPassesNoShadow;
综上所述,需渲染的物体分别经过RenderPriorityGroup、RenderQueueGroup分类后,由RenderQueue统一管理。
三、场景的组织
1、SceneNode
SceneManager中有个重要的数据成员是mSceneNodes: typedef std::map<String, SceneNode*> SceneNodeList; /** Central list of SceneNodes - for easy memory management. @note
Note that this list is used only for memory management; the structure of the
scene is held using the hierarchy of SceneNodes starting with the root node. However yout can look up nodes this way. */ SceneNodeList mSceneNodes; /// Root scene node SceneNode* mSceneRoot;
从注释中可以知道它的功能。
SceneNode用来组织场景中的objects,主要是管理MovableObject。
从上面的图和SceneManager的类层次比较,可以发现很像抽象工厂模式的组织
第 5 页 共 7 页
OGRE 分析之场景管理------Mythma
结构。
SceneNode的基类Node提供的如下方法就会建立一棵Node树:
通过SceneNodeList就把各个棵Node树连接到一起,形成一片森林。
2、Entity与SceneNode:
有了森林,有了树木,有了树枝,但枝头是光秃秃的,毫无生机。而Entity就是点缀枝头的叶子、花朵、果实。
通过SceneNode的如下方法,OGRE把Entity挂接到SceneNode上:
关于Entity和SceneNode的关系, http://www.yanchen.com/ 画了这样一幅图,在此借用一下:
四、场景的建立
第 6 页 共 7 页
OGRE 分析之场景管理------Mythma
(略)
第 7 页 共 7 页
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值