第一课课程介绍:
这一课中,我们将会给你介绍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模式同理。
另外,OgreSDK中debug模式下的dll和cfg文件都有_d后缀,用以区分哪些是Debug模式的,哪些是Release模式的。
翻译到这里,发现原文废话很多。。我就不进行全部翻译了。将会翻译部分并以自己的理解进行述说。
Ogre如何工作?
SceneManager:
当你将物体放进场景中时,一切将会由SceneManager来管理。SceneManager将会与所有你创建的物体保持关联。
Entity:
Entity是可以渲染进场景的一种类型的Object。你也可以把它当作用3D mesh表现出来的任何东西。一个机器人可以是一个Entity,一条鱼也可以是一个Entity。你的人物行走的地形也可以是一个非常大的Entity。但是像灯光,粒子,摄像机等,不是Entity。
这里需要说明的是,你并不能直接将Entity放置在场景中。你必须将Entiy与SceneNode绑定。而SceneNode中,将会包含关于location和orientation的信息。这也是Ogre中的一个特点:将渲染的物体和他们的location,orientation相分离。
SceneNode:
像上面提到的一样,SceneNode包含所有与他关联的Object的location和orientation信息。当你创建一个Entity,它将不会被渲染到场景中,除非你将它与一个SceneNode绑定。
SceneNode允许任意数量的Object与其关联。举个例子:如果你有一个游戏角色在地面上行走,你需要一个灯光照亮他的周围。那么首先你可以创建一个SceneNode,然后创建一个人物Entity与SceneNode关联,接着创建一个Light同样与SceneNode关联。
另外,SceneNode也可以与其他SceneNode关联起来,这样允许你创建一个节点的复杂层关系。我们将会在以后的课程中详细讲解。
最后还有一个很重要的概念是,SceneNode的位置将一直相对与它的父节点。并且SceneManager将包含一个其他SceneNode用来关联的根节点(root node)。也就是所有SceneNode的最终父节点将会是SceneManager的root 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