本次教程的主要目的是介绍一下OGRE最基础的构架:
1.场景管理器
2.场景节点
3.实体
虽然本次教程不会接触到太多的代码,而是把侧重点放在了基础知识的讲解上,但是希望大家一点一点积累对代码的理解,这样才能更彻底的理解一些抽象的概念。
我们先新建一个OGRE项目,OgreApp01。
添加一个h文件TutorialApplication.h,在里面添加如下内容:
#include "ExampleApplication.h"
class TutorialApplication : public ExampleApplication
{
public:
TutorialApplication()
{
}
~TutorialApplication()
{
}
protected:
void createScene(void)
{
}
};
再创建一个新的cpp文件,TutorialApplication.cpp:
#include "TutorialApplication.h"
#include "windows.h"
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
{
TutorialApplication app;
try
{
app.go();
}
catch( Exception& e )
{
MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
}
}
没错,它弹出了一个OGRE的渲染选项界面,点击OK运行:
在此我们不用管太多,只要知道,这是我们创建的第一个项目,相当于是一个HelloWorld的应用。
下面我们来简单的讲一讲OGRE的运行机制,场景管理器、场景节点、实体,这三个类是所有OGRE程序的基石。
1.场景管理器:
在屏幕上显示的所有东西都是由场景管理器来管理。
当您在场景中添加物体时,场景管理器会记录这些物体的位置。
当您添加平面、灯光时,场景管理器同样会管理他们。OGRE里有很多种场景管理器,他们各司其职,有的渲染地面,有的渲染BSP表等等。
在后面,我们会进一步的了解场景管理器。
2.实体
一个实体是可以在场景中渲染的任何物体。
您可以把实体理解为任何一个空间的模型。一个雪人,一个电脑,一个教室,都是一个实体。但是灯光,摄像机,粒子,广告牌等不能成为实体。
不过我们不能把实体直接放在场景中,因为实体和场景节点是绑在一起的。
3.场景节点
场景节点持续跟踪与它绑在一起的实体的方位。
当你创建了一个实体时,它必须和一个场景节点绑定,否则不能被渲染。
同样,一个场景节点也不能单独的在屏幕上显示出来,只有与一个实体绑定后才能在屏幕上显示,而一个场景节点可以绑定多个实体,同样可以与其它场景节点绑定以描述更完整的对象。
例如要实现在屏幕上有个行走的人物对象,并且希望这个对象产生发光效果。
1.首先你需要创建一个场景节点
2.然后再创建一个人物对象的实体并与场景节点绑定在一起
3.之后你还需要创建一个光照模型也与这个场景节点绑定在一起
下面我们来继续改进一开始的项目,通过一些代码来熟悉熟悉OGRE的开发。
返回到我们刚才创建的代码,找到 TutorialApplication::createScene成员函数。
首先需要为整个场景设置环境光,这样才可以看到要显示的内容,调用场景管理器mScene的setAmbientLight函数即可。
参数为环境光的颜色,指定的颜色由红、绿、蓝三种颜色组成,且每种色数值范围在0~1的范围中。
修改TutorialApplication.h文件中的createScene函数,使用以下代码创建一个白色的环境灯点光源:
void createScene(void)
{
mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) );
}
下一步创建一个实体Entity,通过调用 SceneManager的 createEntity 方法来创建:
void createScene(void)
{
mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) );
Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );
}
变量 mSceneMgr 是当前场景管理器的一个对象,createEntity方法有几个参数:
第一个参数是为所创建的实体指定一个唯一的标识,相当于实体的姓名,
第二个参数"robot.mesh"指明要使用的网格实体。("robot.mesh"网格实体在 ExampleApplication 类中被装载,所以我们不用考虑装载的问题)
这样,就已经创建了一个实体Entity,但还需要创建一个场景节点来与它绑定在一起。
每个场景管理器都有一个根节点,所以我们在根节点下创建一个新的场景节点:
void createScene(void)
{
mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) );
Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );
}
这句代码首先调用场景管理器的 getRootSceneNode方法来获取根节点,再使用根节点的 createChildSceneNode方法创建一个名为"RobotNode"的场景子节点。
与实体的名字一样,场景节点的名字也是唯一的,是场景节点的唯一标示。
最后,只需要将实体与场景节点绑定在一起,这样机器人(Robot)就会在指定的位置被渲染:
void createScene(void)
{
mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) );
Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );
node1->attachObject( ent1 );
}
编译并运行你的程序,在屏幕上你将看到一个机器人:
好吧,这个机器人为什么歪着对着我们,怎么样才能和它面对面呢?
下一章我们来讲讲OGRE的坐标系统。