`

Ogre游戏开发 第一课 SceneManager,SceneNode和 Entity Objects

 
阅读更多

第一课课程介绍:

这一课中,我们将会给你介绍Ogre中非常基础的组件:SceneManager, SceneNode 和 Entity Objects。 为了让你能更好的开始学习Ogre,我们将重点集中在一般的概念上,而不会覆盖大片的代码。

当你开始这个课程时,你应该慢慢的将一些代码添加到自己的工程中,然后运行看看效果。

课程开始:

在这个课程中,我们将会使用已经构建好的基础代码。除了我们将添加进createScene方法中的代码,其他的暂时可以忽略掉。在后面的课程中,我们将会深入的解释Ogre程序是如何工作的,但是现在我们只需要从最简单的开始。

创建一个名叫Tutorial的项目。

将Tutorialapplication framework加进项目。(译者注:Tutorialapplication framework是官方提供的一个简单的Ogre框架,已经写好了基本的架构,可以直接往createScene中添加场景构建的相关代码并运行)。

BaseApplication.h
BaseApplication.cpp
TutorialApplication.h
TutorialApplication.cpp

除了使用官方的Tutorial application framework外,也可以使用Ogre AppWizard来创建工程。(译者注:Ogre AppWizard是一个Ogre项目的创建向导,支持VS2005,VS2008,VS2010,QtCreator等)

OgreAppWizard下载地址: https://bitbucket.org/jacmoe/ogreappwizards/downloads

TutorialApplication.cpp是这一课我们唯一用到的文件。我们将只修改createScene()方法。

TutorialApplication.cpp应该包含如下的代码:

#include "TutorialApplication.h"
TutorialApplication::TutorialApplication(void)
{
}
TutorialApplication::~TutorialApplication(void)
{
}
//-------------------------------------------------------------------------------------
void TutorialApplication::createScene(void)
{
 //设置场景的环境光
 mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f,0.5f,0.5f));
 //创建一个Entity
 Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head","ogrehead.mesh");
 //创建一个SceneNode,然后将Entity与其关联起来。
 Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
 headNode->attachObject(ogreHead);
 //创建一个Light,然后设置它的位置
 Ogre::Light* light = mSceneMgr->createLight("MainLight");
 light->setPosition(20.0f,80.0f,50.0f);
}
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif
#ifdef __cplusplus
extern"C"{
#endif
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
 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( Ogre::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
 std::cerr<<"An exception has occured: "<< e.getFullDescription().c_str()<< std::endl;
#endif
 }
 return0;
 }
#ifdef __cplusplus
}
#endif

那么接着,编译然后运行这个程序来确保环境设置正确。你可以使用W S A D键来移动,使用鼠标来移动视角,Escape键退出这个程序。

如果你的VisualStudios项目使用的Unicode编码,那么可能报以下错误:

error C2664:'MessageBoxW': cannot convert parameter 2 from 'const char *' to 'LPCWSTR'
 Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

出现这个问题的原因是,MessageBox函数需要Unicode编码的字符串,而我们给它的是ANSI字符串。

为了解决这个问题,我们可以修改如下:

MessageBoxA( NULL, e.what(),"An exception has occurred!", MB_OK | MB_IConerror | MB_TASKMODAL);

或者你可以将你的编译器文本编码由Unicode改为ANSI。无论如何,你将失去国际化语言的支持。

(译者注:由于我们在使用Ogre时,大多数时候都会使用中文,根据我使用的情况来看,一般把编译器编码改为UTF-8,使用Ogre的framework通常就不会报错了。)

如果你运行程序提示你丢失DLL或者配置文件(.cfg),那么你可能没有将OgreSDK文件夹下面的资源拷贝过来。如果你是Debug模式运行,那么你必须拷贝所有的”.dll”和”.cfg”到[ProjectFolder]\bin\debug目录下,release模式同理。

另外,OgreSDKdebug模式下的dllcfg文件都有_d后缀,用以区分哪些是Debug模式的,哪些是Release模式的。

翻译到这里,发现原文废话很多。。我就不进行全部翻译了。将会翻译部分并以自己的理解进行述说。

Ogre如何工作?

SceneManager

当你将物体放进场景中时,一切将会由SceneManager来管理。SceneManager将会与所有你创建的物体保持关联。

Entity

Entity是可以渲染进场景的一种类型的Object。你也可以把它当作用3D mesh表现出来的任何东西。一个机器人可以是一个Entity,一条鱼也可以是一个Entity。你的人物行走的地形也可以是一个非常大的Entity。但是像灯光,粒子,摄像机等,不是Entity

这里需要说明的是,你并不能直接将Entity放置在场景中。你必须将EntiySceneNode绑定。而SceneNode中,将会包含关于locationorientation的信息。这也是Ogre中的一个特点:将渲染的物体和他们的locationorientation相分离。

SceneNode

像上面提到的一样,SceneNode包含所有与他关联的Objectlocationorientation信息。当你创建一个Entity,它将不会被渲染到场景中,除非你将它与一个SceneNode绑定。

SceneNode允许任意数量的Object与其关联。举个例子:如果你有一个游戏角色在地面上行走,你需要一个灯光照亮他的周围。那么首先你可以创建一个SceneNode,然后创建一个人物EntitySceneNode关联,接着创建一个Light同样与SceneNode关联。

另外,SceneNode也可以与其他SceneNode关联起来,这样允许你创建一个节点的复杂层关系。我们将会在以后的课程中详细讲解。

最后还有一个很重要的概念是,SceneNode的位置将一直相对与它的父节点。并且SceneManager将包含一个其他SceneNode用来关联的根节点(root node)。也就是所有SceneNode的最终父节点将会是SceneManagerroot node

第一个Ogre程序:

下面我们将会回到之前写的代码中。

我们做的第一件事是添加了一个环境光。

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

我们可以通过Ogre::ColourValue来获取指定的环境光颜色。三个参数分别是Red Green Blue。范围从0.0f ~1.0f。

接下来,我们要做的事是创建一个Entity。我们可以通过SceneManager的createEntity来实现。

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

这里可以说明一下,mSceneMgr是一个SceneManager的实例,是在BaseApplication类中创建的。由于这些将会在以后的课程中讲到,现在不必了解它是如何创建的。

createEntity函数中,第一个参数为Entity的名称,所有的Entities必须只有唯一的名称。如果你创建两个相同名称的Entity,将会报错。第二个参数”ogrehead.mesh”指定了我们将用到Entity的mesh文件。这个文件应该在resources.cfg(Debug模式下resources_d.cfg)中定义的资源目录中。这些将会在以后的课程中讲到。

现在我们已经创建了Entity,根据上面的说明,我们必须创建一个SceneNode,然后将它绑定起来。

 Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");

这一行代码,首先通过SceneManager的getRootSceneNode函数获取根节点。然后调用根节点的createChiledSceneNode来创建SceneNode。同样的,SceneNode的名称也必须唯一。

接下来,我们将Entiy与SceneNode绑定。

 headNode->attachObject(ogreHead);

虽然灯光是下一个课程中的内容,但为了让我们用更加合适的明暗效果来看模型。我们需要添加一个灯光,而不是仅仅使用环境光。

我们将给灯光赋予一个唯一的名称。

 Ogre::Light* light = mSceneMgr->createLight("MainLight");

创建好灯光后,我们通过SetPosition方法来设定灯光的位置。这三个参数分别代表X,Y,Z坐标。

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

运行程序后,我们将会看到下面的画面。一个大大的食人魔脑袋。。。当然,这也是Ogre的标志。

至于3D世界的坐标系,请看下图。稍微了解3D的应该都知道。就多做解释了。

接下来,我们将会说明SceneNode在3D世界中的变换。

平移变化:

Ogre中SceneNode使用translate函数来进行平移变化。

 headNode2->translate( Ogre::Vector3(10,0,10));

缩放变化:

SceneNode使用Scale函数来进行缩放变化。

 headNode->scale(.5,1,2);

旋转变化:

旋转变化包括yaw,pitch 和 roll 三个函数。

 headNode->yaw( Ogre::Degree(-90));

 headNode2->pitch( Ogre::Degree(-90));

 headNode3->roll( Ogre::Degree(-90));

其中,yaw是绕Y轴进行旋转, pitch是绕X轴进行旋转, roll是绕Z轴进行旋转。Ogre::Degree用于生成Ogre中表示的角度。

配置文件:

最后我们稍微介绍下Ogre中比较重要的几个配置文件。同样的,以下的为release模式下配置文件,debug模式请加上_d后缀。

plugins.cfg 这个配置文件将会包含你的Ogre程序中将要用到的插件。由于Ogre默认支持OpenGL渲染和DirectX渲染。。所以如果你没有安装DirectX, 那么就把plugins.cfg中关于directX的插件删掉,以免报错。

resources.cfg 这个配置文件主要是定义你的Ogre程序中将要使用到的资源文件。稍微看看Ogre SDK目录中的resources.cfg就会知道大致怎么回事。 另外由于现在的版本Ogre不在使用CEGUI作为默认的UI库,将CEGUI和Ogre整合时,CEGUI的资源路径也将在这个配置文件中定义。

ogre.cfg这个配置文件主要是定义游戏运行时的分辨率啊,是否全屏啊等之类的参数。如果你使用的官方的Tutorial application framework基础上进行开发,那么在游戏启动时,会有Ogre的配置文件选择窗口,里面修改的参数将会同步更改到ogre.cfg。


Ogre第一课就到此结束了。前面一部分是翻译,后面是翻译加自己的话。突然发现翻译一篇文章,里面实在废话太多。估计以后还是自己写教程好了。


转载请注明出处:http://blog.csdn.net/ml3947


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics