ogre研究之第一个程序(二)
接续(一)
首先,我们要分析的就是Root类,使用Ogre的程序所需要作的第一件事情就是实例化一个Root对象。如果没有这个对象,你就无法调用(除了日志管理以外)的任何一个功能。Root类的构造函数接受一些符串对象的参数,这些字符代表着不同作用的文件名称。
- Root * root = new Root();
- Root * root = new Root("plugins.cfg");
- Root * root = new Root("plugins.cfg", "ogre.cfg");
- Root * root = new Root("plugins.cfg", "ogre.cfg", "ogre.log");
- Root * root = new Root("", "");
上面列出了一些不同的方法来创建Root实例,这里面任何的方法都能单独的正确执行。参数也是系统所默认的值(“plugins.cfg”, “ogre.cfg”, “ogre.log”——当你没有填写参数的时候,系统就认为采用了默认的这些值)。
plugins.cfg:插件,Ogre中所谓的插件就是符合Ogre插件接口的代码模块,比如场景管理(SceneManager)插件和渲染系统(RenderSystem)插件等。在启动的Ogre时候,他会载入plugins.cfg配置文件来查看有哪些插件可以被使用。下面是一个plugins.cfg文件例子
- # Defines plugins to load
- # Define plugin folder
- PluginFolder=.
- # Define plugins
- Plugin=RenderSystem_Direct3D9_d
- Plugin=RenderSystem_GL_d
- Plugin=Plugin_ParticleFX_d
- Plugin=Plugin_BSPSceneManager_d
- Plugin=Plugin_CgProgramManager_d
- Plugin=Plugin_PCZSceneManager_d.dll
- Plugin=Plugin_OctreeZone_d.dll
- Plugin=Plugin_OctreeSceneManager_d
其中PluginFolder用于定义这些插件存在的位置(路径), 这里使用“.”,表示需要在“\”或者“/”(即根目录)。在某些平台上可以不使用“.”直接使用""(空白),ogre照样会在“\”或者“/”中去找。
而Plugin则说明了有哪些插件可以使用,但是需要注意,这些插件都没有后缀名。
这里需要注意:在“=”两边不能加入空格或者 Tab字符。
ogre.cfg则是一个属性配置文件,主要保存用户自定义的一些属性,即下图所示的界面的一些属性。
文件如下:
- Render System=Direct3D9 Rendering Subsystem
- [Direct3D9 Rendering Subsystem]
- Allow NVPerfHUD=No
- Anti aliasing=None
- Floating-point mode=Fastest
- Full Screen=No
- Rendering Device=Mobile Intel(R) 945 Express Chipset Family
- VSync=No
- Video Mode=800 x 600 @ 32-bit colour
- sRGB Gamma Conversion=No
- [OpenGL Rendering Subsystem]
- Colour Depth=32
- Display Frequency=N/A
- FSAA=0
- Full Screen=No
- RTT Preferred Mode=FBO
- VSync=No
- Video Mode=1024 x 768
- sRGB Gamma Conversion=No
相信这里就不用多解释,大家都明白了。
Ogre.log :日志文件,用于输出一些调试信息等,比如下代码:
- LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***")
就会在 Ogre.log文件中输出"*** Initializing OIS ***"信息。
另外需要说明得就是FrameListener接口了,当Ogre渲染每一帧的开始和结束的时候会回调FrameListener接口的方法,其中主要包括如下两个渲染方法。
- class ExampleFrameListener : public FrameListener{
- public:
- bool frameStarted (const FrameEvent &evt);
- bool frameEnded (const FrameEvent &evt );
- };
- bool ExampleFrameListener::frameStarted (const FrameEvent &evt){
- //在每一帧画面渲染前
- return true;
- }
- bool ExampleFrameListener::frameEnded (const FrameEvent &evt ){
- //在每一帧画面渲染后
- return true;
- }
所以我们就可以根据需要来实现这两个方式,实现渲染。
注意:在新的版本中frameRenderingQueued方法基本上取代了frameStarted,所以本例中我们就是用了frameRenderingQueued,一般在这个函数中都需要检测各种输入设备的情况,以进行相应的处理。
最后,当我们在程序中调用mRoot->startRendering();方法时,就告诉ogre,我们需要开始渲染了。ogre就会开始渲染。也正是ExampleApplication类中的go方法,所做的,初始化(setup)完成之后就开始渲染(mRoot->startRendering())。
之所以有了这两个类,上一篇中我们才可以不写任何代码就可以构建一个窗口,那么本节内容,我们要显示模型当然就很简单了。
直接在OgreDemo1类的createScene方法中来实现,
1:设置环境光,首先需要为整个场景设置环境光,这样才可以看到要显示的内容,通过调用setAmbientLight函数并指定环境光的颜色就可以做到这些。指定的颜色由红、绿、蓝三种颜色组成,且每种色数值范围在 0 到 1 之间。
- //设置环境光
- mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) )
2:创建一个 Entity (物体),通过调用 SceneManager 的 createEntity 方法来创建
- //创建一个物体
- Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );
变量 mSceneMgr 是当前场景管理器的一个对象,createEntity 方法的第一个参数是为所创建的实体指定一个唯一的标识,第二个参数 "robot.mesh" 指明要使用的网格实体,"robot.mesh" 网格实体在 ExampleApplication 类中被装载。这样,就已经创建了一个实体。
3:还需要创建一个场景节点来与它绑定在一起。既然每个场景管理器都有一个根节点,那我们就在根节点下创建一个场景节点。
- //创建该物体对应的场景节点
- SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );
首先调用场景管理器的 getRootSceneNode 方法来获取根节点,再使用根节点的 createChildSceneNode 方法创建一个名为 "RobotNode" 的场景节点。与实体一样,场景节点的名字也是唯一的。
4:最后,将实体与场景节点绑定在一起,这样机器人(Robot)就会在指定的位置被渲染:
- //将该物体和场景节点关联起来
- node1->attachObject( ent1 );
ok,现在编译运行你的程序,就可以看到我们伟大的机器人界面了。
最后说一下,在创建Root对象时的文件一般会和程序最后的可执行文件在同一目录(因为有人说找不到这些文件)。祝你成功!
补充一下:
需要将sdk下的media文件夹拷贝到该项目目录下,因为里面存放了一些资源文件,本文中的机器人模型也在其中。
转载于:https://blog.51cto.com/yarin/382510