【Ogre开发】之三:Ogre是如何工作的?场景管理 场景节点 实体

来源:互联网 发布:web数据挖掘的分类 编辑:程序博客网 时间:2024/06/04 17:42

Ogre是如何工作的?场景管理 场景节点 实体



本章由cowboylym(酒劍仙采葡萄)编写,转载请注明出处。 

作者:酒劍仙采葡萄    邮箱: cowboylym@163.com  


接着上一节的内容 我们是如何将食人魔头像放到窗口里的?这要从Ogre的工作方式开始讲起了。

首先我们要先了解什么是场景管理器(SceneManagers)场景节点(SceneNodes)以及实体(Entities)这三样东西。这三个类是Ogre应用程序的基本结构单元。

 

场景管理器(SceneManager)


所有出现在屏幕上的东西都是由场景管理器管理的,当你在场景中放入一个物体时,场景管理器就会一直跟踪他们的位置,当你创建相机(在下一节会具体讲相机)来查看这个场景的时候,管理器也会一直跟踪相机的,当你创建位面、公告板、光源…等等 这些的时候,管理器同样一直跟踪着他们。

 
Ogre里有多种类型的场景管理器、有专门用来渲染地形的、有用来渲染BSP地图的等等。在后续的教程中我们会接触到更多的其他类型的场景管理器。
 

实体(Entity)


实体是一种我们可以在场景中进行渲染的一个对象。你可以把实体想象成用3D网格模型展现出来的任何对象。一个机器人、一条鱼甚至整个地形都是一个大大的实体。但是像 光源、公告板、摄像机、粒子等都不是实体。
 

有一点需要注意的是Ogre把被渲染的物体和该物体所在的位置信息以及方向信息给分离开来了。这意味着,你不能直接将一个实体放到场景中去。你必须将实体挂接到一个场景节点(SceneNode)上。而这个场景节点包含了该物体的位置和方向信息。
 

场景节点(SceneNode)


就像我们刚刚提到的那样,场景节点、对挂接到它上面的所有物体的位置和方向信息都进行看跟踪。当你创建一个实体并将它挂接到一个场景节点上它才会被渲染。另外实体并不是最终显示在屏幕上的物体。只有将实体挂接到你创建的场景节点上之后,这个东西才会显示在屏幕的上。

 
场景节点可以挂接任意数量的物体。假设你要创建一个角色在屏幕上走动,并且有光源伴随着他。首先你要创建一个节点,然后为这个角色创建一个实体,并将实体挂接到节点上,接着你还需要创建一个光源,并且也将它挂接到同一个节点上。场景节点本身也可以被挂接到其他的节点上。由此可以产生不同层次的节点。在后续章节中我们会接触到更多场景节点的高级用法。

 
一个重要的概念需要记住,场景节点的位置都是相对于它的父节点的,每一个场景管理器都有一个根节点,所有的场景节点都挂接在它上面。

 

好了了解了上面的三个概念之后,让我们回到上一章最后我们的食人魔头像的例子上来。我们找到TutorialApplication::createScene 这个函数的定义。在这个教程里 我们只会对这个成员函数进行改写。

 

第一步我们要做的就是创建环境光,这样我们才能看见在场景里的一切行为。我们通过调用setAmbientLight这个函数来实现,该函数需要传递一个颜色参数ColourValue,该结构体包含了红、绿、蓝三原色,他们的值都在0-1之间。

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));

接着我们调用createEntity创建一个实体。

Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");


好了有人要问了,这个mSceneMgr是从哪冒出来的?还有传进去的这两个参数各代表什么意思?首先这个mSceneMgr变量包含了当前的场景管理对象(这是在BaseApplication类中实现的),第一个参数是这个实体的名称,所有的实体必须有唯一的名字,如果出现实体重名Ogre会报错,第二个参数"ogrehead.mesh"是我们要用在这个实体上的网格模型(也就是那个食人魔头像),"ogrehead.mesh"是OgreSDK自带的一个资源文件。文件具体位置在ogre_src_v1-8-1\Samples\Media\models下面。具体Ogre是如何加载资源在后续教程中再详细介绍。

 

实体创建完毕后我们创建一个场景节点,由于每个场景都有自己的根节点root,所以我们创建出来的场景节点都是它的子节点

Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
如上面的代码所示,首先我们调用getRootSceneNode来获取场景根节点,然后由根节点调用createChildSceneNode来创建子节点,“HeadNode”为节点名,所有的场景节点名也都是唯一的。


接下来我们将刚刚创建的实体挂接到这个新建的场景节点上

headNode->attachObject(ogreHead);
然后我们需要创建一个光源(关于光源的细节在下一节中会讲)

Ogre::Light* light = mSceneMgr->createLight( "MainLight" );
并且设置一下光源的位置

light->setPosition(20, 80, 50);

三个参数分别代表X,Y,Z,轴的坐标。

环境光和光源 区别在哪?

举个例子,你想一下晚上你在房子里开了一灯吊在房子中央。。。那就是:点光源。白天。。你站在没有太阳的室外,照亮整个大地的是:环境光。通常可以使用点光或者平行光等来模拟从四面八方照来光线的环境光.......那就得用灯光阵列了。。。。。

环境光无衰减,点光源有。上几张图 可能会更容易懂一点

第一盆花没有加点光源。



第二盆花加了点光源。

 

看见区别了吧。

有兴趣的可以把代码中的

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));

light->setPosition(20.0f, 80.0f, 50.0f);

这两句话分别注释掉然后运行下程序 看看会有什么不同的效果。


以上就是本节所要讲的全部内容,本打算下一章讲灯光、相机和阴影的 但看了下官方教程。决定先讲一下Ogre的屏幕坐标系吧。

 
To be continued...


                                                                                                                                                                                  ————貳零壹叁 年 捌月 肆 日
原创粉丝点击