http://blog.163.com/modingfa_002/blog/static/11092546620091026112721405/
简介:本教程基于Ogre Wiki上的Basic Tutorial系列,并依据笔者使用的vs2005+sp1+OgreSDK1.4.3开发环境简化整理而来,其中穿插着笔者自己的理解。这是教程的第一部分,也是我的学习笔记。正文:凡是翻译过几篇技术类文章的人都深知从头至尾忠实重现作者的原意是一件多么令人头疼的事情。当我从诸多曾经许诺要翻译的文章中爬出来的时候,我决定这次不做那样一个“傻子”,重写那些文章要比翻译它们快乐的多。
-
在开始前,我希望统一我们的开发环境——VS2005+OgreSDK1.4.3。有两点需要注意:
一、请确认你的VS2005安装了sp1补丁包,这一点非常重要,否则你可以正确的编译Ogre程序,但你死活运行不起它们来。下面介绍SP1的安装步骤和注意事项:
微软的Visual Studio 2005 Service Pack 1 (SP1)年前就发布了,年前终于有点时间了,于是装了一下VS2005 sp1,看看到底有什么好东西。这次发布的语言版本包括十个国家的语言,可谓全上阵,容量为413M修正了许多bug,其中包括了很多人最最关心中文的Web Application Project问题。
VS2005 SP1下载地址:
VS2005 SP1英文正式版 431M
VS2005 SP1中文正式版440M
VS2005 SP1号称是M$有史以来最bt的补丁,据说有人装了3个多小时还在收集信息……,为了让大家少走弯路,现总结一下供大家参考。
安装注意事项:
1.安装时间会非常长,如果机器配置不是很高的话需要2个小时,一般的话也需要1个小时左右所以请耐心等待。
2.安装前检查你的c盘是否有大于3G的空余空间,因为安装的时候会释放很多临时文件在c盘,如果不能保证大于3g的话可能会发生异常错误,不过我在安装的时候没有占用3G这么恐怖,不过也起码占用了1G多的空间。
3.如果你以前安装过web application project,在安装vs2005 sp1以前请先把他卸载,不然不能成功安装vs2005 sp1
4.vs2005sp1的补丁包是把你机器上所有单独装过vs2005的版本的补丁都打上,如果机器上装了Visual Web Developer Express和Visual Studio team sutie,那么他就要运行安装补丁两次.
安装步骤:
一.解决数字签名认证的问题
1. 单击 开始单击 运行 , 键入 控件 secpol.msc ,然后单击 确定 。2. 双击 本地安全策略。
3. 单击 软件限制策略。
注意 如果列出,没有软件限制右键单击 软件限制策略 ,然后单击 新建策略 。
4. 在 对象类型 , 双击 强制 。
5. 单击 除本地管理员以外的所有用户 , 并单击 确定 。
6. 重新启动计算机。
要点 之后在执行以上步骤,本地管理员可安装 .msi软件包或 .msp 包。 通过以下以前步骤之后安装程序包,重置强制级别。 在步骤 5, 单击 所有用户 代替 除本地管理员以外的所有用户。
二.执行批处理文件来安装
reg export HKLM\Software\Policies\Microsoft\Windows\Installer installer.regreg add HKLM\Software\Policies\Microsoft\Windows\Installer /v MaxPatchCacheSize /t REG_DWORD /d 0 /f
net stop msiserver
start /waitVS2005sp1-KB926604-X86-CHS.exe
reg delete HKLM\Software\Policies\Microsoft\Windows\Installer /v MaxPatchCacheSize /f
reg imp
ort installer.reg net stop msiserver
del /q installer.reg 2>nul
看看效果
二、请确认你的Ogre是合适的版本,也就是OGRE 1.4.3 SDK for Visual C++ .Net 2005(8.0)SP1,你可以从http://www.ogre3d.org/index.php?option=com_content&task=view&id=411&Itemid=131免费获得。
创建你的第一个Ogre应用程序现在,对表之后,行动开始。哦,等一下,忘了给你们发枪了。请到http://ogreconglo.sourceforge.net/phpBB2/viewtopic.php?p=4领取枪械。是Ogre产的Ogre Application Wizard,不要着急,人人都有。把它解压到合适的位置,我推荐的位置当然是OgreSDK目录下了,然后运行里面的VC8_Setup.js安装。兄弟们,准备好了吗?现在行动真的要开始了。
打开vs2005,新建一个项目,"文件"->"新建"->"项目"->"Visual C++",在"Visual Studio已安装的模板"选择"OGRE SDK Application"。设置好工程名和存储路径后点"确定"按钮。
弹出了向导,选项保持默认就好了,点"finish"完成。
是不是个Win32项目的向导一样简单?下面按F7编译一下。
如果没有操作失误的话,会得到这样的结果
------ 已启动生成: 项目: test1, 配置: Debug Win32 ------
正在编译...
test1.cpp
正在编译资源...
正在编译资源清单...
正在链接...
正在嵌入清单...
Copying exe to samples bin directory ...
已复制 1 个文件。
生成日志保存在“file://d:GameDevelop est1 est1objDebugBuildLog.htm”
test1 - 0 个错误,0 个警告
========== 生成: 1 已成功, 0 已失败, 0 最新, 0 已跳过 ==========运行却会出现如图的错误,缺少相应的文件,运行不起来。一种解决办法是把缺少的文件复制过来,但你必须知道需要什么文件,不适合新手。另一种方法是,你注意到“Copying exe to samples bin directory ...”一句了吗?EXE文件拷贝到哪里去了?拷贝到“\OgreSDK\bin\debug”中去了,找到了吗?运行试试,成功了吧。
揭开向导的面纱
你可能在想Ogre Application Wizard(之后简称OAW)到底做了什么呢?就像当初我使用Win32应用程序向导创建了那个HelloWorld之后想的一样。其实OAW只做了两件事,一是创建了几个源文件,另一个是设置了IDE的参数,这也是最重要的一步。下面我们来手动做一次OAW做的事情,以便加深印象,为了以后的方便又一小部分操作是不同的。
关闭刚才的解决方案,新建一个项目,"文件"->"新建"->"项目"->"Visual C++"->"Win32",在"Visual Studio已安装的模板"选择"Win32项目"。设置好工程名和存储路径后点"确定"按钮。(我用的工程名和解决方案名都是test2,路径名为 D:\GameDevelop)
在向导的"应用程序设置"中选择"Windows应用程序"和"空项目",点击完成。
除了几个工程文件,向导没再多做任何事情。为了这个项目的独立性与方便性,我们还要复制"\OgreSDK"下的"\bin"和"\media" 到"D:\GameDevelop\test2"里,并创建"include"、"src"和"scripts",这样你在"D: \GameDevelop\test2"下将看到6个文件夹。
然后创建一个"SampleApp.cpp",保存路径为"D:\GameDevelop\test2\src",内容如下:
#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
MessageBoxA( NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
fprintf(stderr, "An exception has occurred: %s ",
e.getFullDescription().c_str());
#endif
}return 0;
}保存,按F7编译一下。
------ 已启动生成: 项目: test2, 配置: Debug Win32 ------
正在编译...
SampleApp.cpp
d:gamedevelop est2srcsampleapp.cpp(1) : fatal error C1083: 无法打开包括文件:“ExampleApplication.h”: No such file or directory
生成日志保存在“file://d:GameDevelop est2 est2DebugBuildLog.htm”
test2 - 1 个错误,0 个警告
========== 生成: 0 已成功, 1 已失败, 0 最新, 0 已跳过 ==========出错了,找不到"ExampleApplication.h"。其中的"ExampleApplication"又是什么呢?它是Ogre为初学者设计的实例程序类(可能是个程序框架什么的,我是这么理解的),以便你可以快速的开始Ogre编程的学习。"ExampleApplication.h" 在"\OgreSDK\samples\include"下。默认情况下,IDE是不会找到这里的。还记得我说过Ogre程序向导做过什么吗?对了,设置我们的IDE环境。下面我们就来一步步地把IDE设置好。
"项目"->"属性",打开"test2 属性页",展开"配置属性"。设置:
"调试"->"工作目录"为"..\bin\Debug",
"C/C++"->"常规"->"附加包含目录"中添加"..\include"、"$(OGRE_HOME)\include"和"$(OGRE_HOME)\samples\include",sample中的include现在在ogre_src_v1-8-0\Samples\Common\include里
"C/C++"->"代码生成"->"运行时库"为"多线程调试 DLL (/MDd)"(这个好像就是默认的),
"链接器"->"常规"->"输出文件"为"..\bin\Debug\$(ProjectName).exe",
"链接器"->"常规"->"附加库目录"中添加"$(OGRE_HOME)\lib",
"链接器"->"输入"->"附加依赖项"中添加"OgreMain_d.lib"和"OIS_d.lib"(如果是Release版则添加"OgreMain.lib"和"OIS.lib") -
设置好了,再编译一次试试。如果你看懂了以上部分,并且编译通过的话,我们就可以继续了,之后的内容将修改前面这个程序来向你展示Ogre的世界。
OGRE是如何工作的SceneManager、Entity和SceneNode是Ogre的3个基础模块。
其中SceneManager是管理者,所有显示在屏幕上的东西都由SceneManager管理。SceneManager的类型众多,随着教程的推进,你会慢慢的了解它。
Entity就是你想要渲染的物体的模型,它们使用mesh(Ogre使用的一种文件格式)描述。在Ogre中你需要注意,物体模型是与它的位置和方向分开的。这就意味着你不能直接把一个物体放在场景里,你必须将Entity和一个SceneNode相关联,而这个SceneNode包含了位置和方向的信息。
正如前面所说,SceneNode可以和Entity相关联,关联的数量是不受限制的。这有什么用处呢?例如,你想制作一个人物在屏幕上行走,同时有一圈神圣的光环绕着他。实现这个的一种方法就是先创建一个SceneNode,然后创建一个人物的Entity并与SceneNode关联。接着再创建一个光的Entity也与SceneNode关联。人和光就这么联系在一起了,简单吧。
SceneNode不光可以和Entity相关联,和其他的SceneNode关联也是允许的。这将有助于你创建结构层次复杂的游戏世界。如果你不太明白,就想想windows中的窗口,子窗口套在父窗口里,层层嵌套就组成了一个程序的界面,而这里组成的是游戏世界的一部分,可能是人、房子,也可能是些别的什么东西。
SceneNode可以有孩子(ChildSceneNode),当然也就有父亲(ParentSceneNode)。(典型的树状结构嘛)
windows中所有窗口的根都是桌面(Desktop),在Ogre中每一个SceneManager也有这样一个根(RootSceneNode),它和其他所有的SceneNode关联着。
一个更加丰富的世界刚才创建的程序中空荡荡的,除了数值和Logo什么也没有。现在我们添加一些代码让这个世界丰富起来。在刚才的代码中找到TutorialApplication::createScene成员函数,今天后面的代码都是添加在这个函数中的。
为了能看清楚我们将要做的事情,首先要设置场景的光线。
mSceneMgr->setAmbientLight(Ogre::ColourValue(1,1,1));然后创建一个物体。
Entity *ent1 = mSceneMgr->createEntity("Robot","robot.mesh");
对了,还要有与之关联的SceneNode。
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("RobotNode");
最后,把它们关联在一起。
node1->attachObject(ent1);
好了,就是它了!编译运行你的程序,你会看到一个机器人站在屏幕上。如果你想了解这几个函数的具体用法请查看"OGRE API Reference",你可以在开始菜单中找到,作用相当于OGRE的MSDN。
坐标和向量在继续深入之前,我们需要讨论一下屏幕坐标和Ogre向量对象。和许多图形引擎一样,Ogre使用x和z轴表示水平面,y轴作垂直轴。现在看着你的显示器,x轴是从你显示器的左边到右边,向右为x的正方向。y轴是从你显示器的底部到顶部,向上为y的正方向。z轴是从你的显示器屏幕内部向外延伸,向外为z的正方向。如图:
我们的机器人为什么是朝向x轴正方向的?这是mesh自身的属性,取决于它是如何设计的。Ogre不对你如何确定你模型的方向作任何假设。你所加载的每一个mesh都有它自己的开始方向。Ogre使用向量(Vector)类而不是点(Point)类来描述位置和方向。向量的定义分2个向量(Vector2)、3个向量 (Vector3)和4个向量(Vector4),其中Vector3最常用。如果你不熟悉向量,我建议你在开始用Ogre做任何事前先复习一下(向量),这对你将来复杂的编程会很有帮助。
下面我们再添加一个物体。
Entity *ent2 = mSceneMgr->createEntity("Robot2","robot.mesh");
SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode("RobotNode2",Vector3(50,0,0));
node2->attachObject(ent2);
跟刚才的代码很像,只是多了几个参数。我们为node2指定了坐标Vector3(50,0,0)。编译运行,你会看到有两个机器人排排站,哈哈。 - 引用通告地址:Http://www.leeya.com.cn/ASTBRec.Asp?LogID=87
#include "ExampleApplication.h"
#include "OgreColourValue.h"
class TutorialApplication : public ExampleApplication
{
protected:
public:
TutorialApplication()
{
}
~TutorialApplication()
{
}
protected:
void createScene(void)
{
mSceneMgr->setAmbientLight(Ogre::ColourValue(1,1,1));
Entity *ent1 = mSceneMgr->createEntity("Robot","robot.mesh");
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("RobotNode");
node1->attachObject(ent1);
}
};
#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
MessageBoxA( NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
fprintf(stderr, "An exception has occurred: %s ",
e.getFullDescription().c_str());
#endif
}
return 0;
}