OGRE学习笔记(一)

OGRE是如何工作的?
这是一个相当宽泛的问题,只研究一点显然不能够得到答案。我们将相继介绍

SceneManagers,Entities,SceneNodes.这三个类是OGRE的基石.
SceneManager 基础:
我们再屏幕上看到的一切都通过SceneManager来管理,当你把一个物体放到场景中去的时候,SceneManager就是我们来跟踪它们位置的类.当你创建了一个相机来观察场景的时候,SceneManager将用来跟踪相机的位置,当你创建了飞机,灯光等等,SceneManager来跟踪他们.
正如我们以后将要看到的一样,有很多中SceneManager,有用来渲染terrain的SceneManager,有用来渲染BSP图的SceneManager等等.
Octree Scene Manager
Terrain Scene Manager
Nature Scene Manager
Paging Scene Manager
BSP Scene Manager
DotSceneOctree SceneManager
我们将再以后详细介绍每个 SceneManager
Entity 基础:
一个Entity就是我们将要渲染到屏幕上的一个对象,我们可以把Entity想象成任何3D网格模型.一个系统任务可以是一个Entity,一条鱼是一个Entity,游戏中的地形也是Entity.但是,灯光,例子,相机等等都不是 Entity.
这里有一点我们需要注意,那就是OGRE将所要渲染的物体与它们的位置分开了,这就意味着我们不能只创建一个Entity,然后把它放置到现场中,只能通过将它与一个SceneNode绑定才能够放置它到场景中,SceneNode中包括了位置的信息.
SceneNode 基础:
在前面我们已经提到,SceneNode中维护着与它绑定的对象的位置,当你创建了一个Entity对象时,只有你将它与一个SceneNode对象绑定时才能在场景中渲染它.它们之间的这种关心时对应的,我们也不能直接将一个SceneNode对象直接在场景中渲染,直到有Entity绑定在它身上.
一个SceneNode可以由很多对象绑定到它身上,比如说有一个人在走动情景,我们想在他周围加上灯光.我们可以这样来实现:让我们首先来创建一个SceneNode对象,然后创建人物Entity,并且把它绑定在先创建的那个SceneNode上,然后我们再创建灯光对象,并且将灯光与SceneNode绑定.不仅如此,SceneNode还可以跟其它的SceneNode绑定,这样就可以形成一个有层次的结构.我们应该记住很重要

的一点,那就是一个SceneNode的位置是跟它父节点的位置是相关的,并且每个SceneManager都包含一个

SceneNode层次结构的根节点.
现在回到我们刚才的"hello world",找到函数:TutorialApplication::createScene,现在我们只关

心这个函数.我们要做的第一件事情就是打开环境光.这通过调用函数setAmbientLight来实现,它接受一

个颜色参数以用来指定光的颜色.这里需要注意的是颜色值RGB的分量都是在0和1之间的.
mSceneMgr->setAmbientLight(ColourValue(1,1,1));
接下来我们就要创建一个Entity,看下面的代码:
Entity *ent1=mSceneMgr->createEntity("Robot","robot.mesh");
Ok,现在你的头脑中肯定产生了很多问题:mSceneMgr是什么?在上个函数中的各个参数的含义是什么?
现在让我来告诉你:mSceneMgr包含了当前的SceneManger对象(ExampleApplication为我们做了这些).再

来看createEntity的参数,第一个参数是我们所要创建的Entity的名字,每个Entity都必须有一个唯一的

名字.如果创建一个同名的Entity就会有错误发生."robot.mesh"是我们所创建的Entity所用到的网格.

我们所要用到的网格被ExampleApplication预先导入了.
好,我们现在创建了Entity,按照我们前面所说,现在该为它创建一个SceneNode.因为每个

SceneManager都有个根节点,现在我们就来创建它的子节点:
SceneNode * node1=mSceneMgr->getRootSceneNode()->createChildSceneNode("RobotNode");
上面的语句首先是调用了getRootSceneNode来得到当前的SceneManager,然后就来创建它的子节点.
参数就是我们所创建的SceneNode的名字,同Entity一样,不能有重名的.
最后我们要把Entity绑定在SceneNode上,以使得Entity有一个位置用来渲染.
node1->attachObject(ent1);
好的,现在就来了编译我们的程序,就将看到一个人物站在场景中.
注意:robot.mesh没有在ogreCore.zip中,修改resources.cfg:
FileSystem=../../media/materials/programs
FileSystem=../../media/materials/scripts
FileSystem=../../media/materials/textures
FileSystem=../../media/models
以使得我们的程序能正常工作.

坐标与向量:
在我们继续之前,先来看一下OGRE中的坐标系跟向量对象. OGRE跟其它的图形引擎一样使用x,z来表

示水平平面, 用y来表示垂直方向.面对你的显示器,x轴是从左到右,右边是正方向;y轴是从下到上,上

方是正方向;z轴是从里向外,外面是正方向.
OGRE是用向量类来表示位置跟方向的,Vector2,Vector3,Vector4是OGRE中定义的三种向量,然而我们

最常使用的是Vector3.在继续前进之前请确定你右足够的向量方面的数学知识,这对以后的学习是非常

重要的.
添加更多对象:
现在你明白了坐标系统如何工作的,现在让我们继续看我们的代码.我们如何来指定对象的位置呢?大

多数的函数都是右默认值的,比如说,SceneNode::createChildSceneNode成员函数右三个参

数:SceneNode的名字,位置,朝向.它的位置,正如我们先前看到的一样默认是在(0,0,0)处,现在让我们来

重新创建一个节点,这次我们让它处在不同的位置:
Entity *ent2 = mSceneMgr->createEntity( "Robot2", "robot.mesh" );
SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(

"RobotNode2", Vector3( 50, 0, 0 ) );
node2->attachObject( ent2 );
这里的代码大多数跟以前是一样的,有两处小区别:一个是名称,再一个就是对象的初始位置,这

次我们是把对象放在了(50,0,0)处.
下面我们来列举一些Entity的常用函数:
setVisible()
isVisible()
getName()
getParentSceneNode()
至于Entity类是如何实现的,大家现在先不要急于了解这些,以后的学习中慢慢体会,一开始就过度

了解细节有可能打击我们的积极性.
SceneNode的一些常用函数:
//位置相关
getPositiion()
setPosition()
translate()
//旋转
scale()
yaw()
roll()
pitch()
resetOrientation()
setOrientation()
getOrientation()
rotate()
//其它
attachObject()
numAttachedObject()
getAttachedObject()
detachObject()
detachAllObjects()

让我们来看一下下面这段代码:
Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode(

"RobotNode" );
node1->attachObject( ent1 );
Entity *ent2 = mSceneMgr->createEntity( "Robot2", "robot.mesh" );
SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(

"RobotNode2", Vector3( 50, 0, 0 ) );
node2->attachObject( ent2 );
如果我们把第五行:
SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(

"RobotNode2", Vector3( 50, 0, 0 ) );
改为:
SceneNode *node2 = node1->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );
现在,RobotNode2是RobotNode的一个子节点,这就意味着node1移动,node2就会跟着移动,但是移动

node2不会影响到node1.下面这行代码就只移动了node2:
node2->translate( Vector3( 10, 0, 10 ) );
下面的这段代码是移动的node1,因为node2是node1的子节点,所以niode2也就跟着移动了.
node1->translate( Vector3( 25, 0, 0 ) );

练习一下这些代码:
缩放:
Entity *ent = mSceneMgr->createEntity( "Robot", "robot.mesh" );
SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );
node->attachObject( ent );
node->scale( .5, 1, 2 );
ent = mSceneMgr->createEntity( "Robot2", "robot.mesh" );
node = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2", Vector3( 50,

0, 0 ) );
node->attachObject( ent );
node->scale( 1, 2, 1 );
旋转:
Entity *ent = mSceneMgr->createEntity( "Robot", "robot.mesh" );
SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode(

"RobotNode", Vector3( -100, 0, 0 ) );
node->attachObject( ent );
node->yaw( Degree( -90 ) );
ent = mSceneMgr->createEntity( "Robot2", "robot.mesh" );
node = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2");
node->attachObject( ent );
node->pitch( Degree( -90 ) );
ent = mSceneMgr->createEntity( "Robot3", "robot.mesh" );
node = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode3", Vector3(

100, 0, 0 ) );
node->attachObject( ent );

node->roll( Degree( -90 ) );

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值