OGRE使用指南:

在这里我们将学习OGRE的方方面面:SceneManager,SceneNode,Entity.我们会重点介绍一些在OGRE中使用的概念.
    随着我们了解得越来越多,我们将能够编写自己得游戏,代码量会越来越大!
    让我们开始吧:
    首先让我们来写一些代码,这些是我们游戏得基本框架,随着我们框架得逐步完善,你将慢慢明白

OGRE的流程:
    #include "ExampleApplication.h"

    class TutorialApplication : public ExampleApplication
    {
    protected:
    public:
         TutorialApplication()
         {
         }

         ~TutorialApplication()
         {
         }
     protected:
         void createScene(void)
        {
        }
    };

    #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
    #define WIN32_LEAN_AND_MEAN
    #include "windows.h"

    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
    #else
    int main(int argc, char **argv)
    #endif
    {
       // Create application object
       TutorialApplication app;

      try {
          app.go();
        } catch( Exception& e ) {
      #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!",

MB_OK | MB_ICONERROR | MB_TASKMODAL);
     #else
         fprintf(stderr, "An exception has occured: %s/n",
                e.getFullDescription().c_str());
     #endif
        }

     return 0;
   }
    如果你是在windows平台下开发,并且已经安装了 OGRE  SDK,确定把"[OgreSDK_DIRECTORY]/samples/include"添加到工程的引用库里面.请先正确编译和运行上面的代码再接着看以下内容,这将使你更加有信心.尽管它运行时只有的界面和一个盒子,这将使OGRE世界中的"Hello World".
   请确定再可执行文件的目录下有以下两个文件:plugins.cfg,resources.cfg.plugins.cfg告诉OGRE将使用哪个运行库(Direct3D9 or OpenGL).Resources.cfg被ExampleApplication所使用并且指定纹理,网格脚本的路径.以上两个文件都使文本文件,必要时编辑它们,以确保路径时正确的。否则将出现错误。
 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值