StupidBeauty
Read times:647Posted at:Fri Dec 16 20:43:34 2011
- no title specified

Irrlicht文档翻译:教程2: Quake3地图 ,Tutorial 2: Quake3Map

这個教程演示的是:如何将一個Quake 3 地图载入到引擎中、创建一個SceneNode 以便对渲染速度进行优化、创建一個由用户控制的摄像机。

注意,在开始这個教程之前,妳应当了解这個引擎的基本用法。如果妳还没看过第一個教程的话,就简单地看看: http://irrlicht.sourceforge.net/tut001.html

像HelloWorld(世界妳好)示例一样开始:我们包含irrlicht 的头文件,还包含另外一個头文件以便让用户从终端中选择使用哪個驱动程序。

#include <irrlicht.h>

#include <iostream>

前面在HelloWorld 示例中已经说过,Irrlicht 引擎的所有东西都可在命名空间'irr'中找到。为咯避免在每個类的名字前面都写上irr::,我们告诉编译器要从现在开始使用那個命名空间,这样我们就不用再写那個'irr::'咯。还有另外5個子命名空间'core'、'scene'、'video'、'io'和'gui'。这次跟HelloWorld 示例不同,我们不对这5個命名空间调'using namespace'用,因为这样妳就可以看看哪些东西在哪個命名空间中咯。但是如果妳喜欢那样做的话,仍然可以像前一個示例那样包含那些命名空间。

using namespace irr;

……

好咯,现在开始。……

int main()

{

就像在HelloWorld 示例中那样,我们用createDevice()来创建一個IrrlichtDevice。不同之处就是这次我们让用户来选择要使用哪個视频驱动程序。其中的Software(软件)设备用来绘制一個巨型的Quake 3 地图的话,會太慢咯,不过勒,我们还是把这個选项加上,以增添一些乐趣。不想(Instead of)把下面这一大坨代码复制到妳的程序中去的话,妳可以简单地包含Irrlicht 中的driverChoice.h头文件。其中的driverChoiceConsole 函数做的正是这件事(让用户选择视频驱动程序)。

//让用户选择驱动程序

video::E_DRIVER_TYPE driverType;

printf("Please select the driver you want for this example:\n"\

" (a) OpenGL 1.5\n (b) Direct3D 9.0c\n (c) Direct3D 8.1\n"\

" (d) Burning's Software Renderer\n (e) Software Renderer\n"\

" (f) NullDevice\n (otherKey) exit\n\n");

char i;

std::cin >> i;

switch(i)

{

case 'a': driverType = video::EDT_OPENGL; break;

case 'b': driverType = video::EDT_DIRECT3D9;break;

case 'c': driverType = video::EDT_DIRECT3D8;break;

case 'd': driverType = video::EDT_BURNINGSVIDEO;break;

case 'e': driverType = video::EDT_SOFTWARE; break;

case 'f': driverType = video::EDT_NULL; break;

default: return 1;

}

//创建设备,如果失败,则退出

IrrlichtDevice *device =

createDevice(driverType, core::dimension2d<u32>(640, 480));

if (device == 0)

return 1; //无法创建选中的驱动。

获取视频驱动和SceneManager(场景管理器)的指针,这样我们就不用每次都调用irr::IrrlichtDevice::getVideoDriver()irr::IrrlichtDevice::getSceneManager()咯。

video::IVideoDriver* driver = device->getVideoDriver();

scene::ISceneManager* smgr = device->getSceneManager();

要显示Quake 3 地图,先得载入它。Quake 3地图是打包存储在.pk3文件中的,而那种文件实际上就是.zip文件。所以我们将那個.pk3文件添加到irr::io::IFileSystem中。 添加完毕之后,我们就可以像对待那些直接存储在硬盘上的文件一样地读取那個压缩包中的文件。

device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3");

现在我们可以调用irr::scene::ISceneManager::getMesh()来载入网孔(mesh)。我们将得到一個指向某个irr::scene::IAnimatedMesh的指针。妳可能已经知道咯,Quake 3地图实际上并不是动态的(animated),它们只是一大批带有某些素材(materials)的静态几何图形(geometry)。所以这個IAnimatedMesh 只有一帧,所以我们取出这個“动画”的“第一帧”,它就是我们的quake 地图(level)。然后用irr::scene::ISceneManager::addOctreeSceneNode()来对它创建一個Octree (八叉树)场景节点(scene node)。八叉树会对场景起到一点优化作用,它尝试着只绘制那些当前可见的几何图形。八叉树的另一個替代品是irr::scene::IMeshSceneNode,它會绘制整个网孔中的全部几何图形,不會进行优化。试试看吧:使用irr::scene::ISceneManager::addMeshSceneNode(),而不是addOctreeSceneNode(),再比较一下由视频驱动绘制的图元(primitives)個数。(在irr::video::IVideoDriver类中有一個irr::video::IVideoDriver::getPrimitiveCountDrawn()方法)。注意,这种八叉树优化只在绘制由大量几何图形组成的海量网孔时才有效果。

scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");

scene::ISceneNode* node = 0;

if (mesh)

node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);

// node = smgr->addMeshSceneNode(mesh->getMesh(0));

因为这個地图不是以原点(origin)(0,0,0)作为中心设计的,所以我们将整个地图做一点转换(translate)。这一点可对irr::scene::ISceneNode地图使用irr::scene::ISceneNode::setPosition()(本例使用的方法)、irr::scene::ISceneNode::setRotation()irr::scene::ISceneNode::setScale()方法来实现。

if (node)

node->setPosition(core::vector3df(-1300,-144,-1249));

现在我们只需要一個观察这個Quake 3 地图的摄像机咯。我们要创建一個由用户控制的摄像机。Irrlicht 引擎中有多个摄像机可用。比如说MayaCamera,可像Maya 中的摄像机一样控制:按住鼠标左键以便旋转、按住两个鼠标键以便缩放、按住鼠标右鍵以便转换(translate)。可用irr::scene::ISceneManager::addCameraSceneNodeMaya()来创建这個。但是在这個示例中,我们想要创建一個像第一人称射击游戏(FPS)中的摄像机那样操作的摄像机,所以我们用irr::scene::ISceneManager::addCameraSceneNodeFPS()

smgr->addCameraSceneNodeFPS();

鼠标光标需要隐藏,所以我们用 irr::IrrlichtDevice::ICursorControl 来隐藏它。

device->getCursorControl()->setVisible(false);

所有东西都做好咯,现在让我们绘制出来吧。我们另外还将当前的帧速率(frames per second)和绘制的图元数显示在窗口的标题中。那個irr::IrrlichtDevice::isWindowActive()测试是可选的,但是能够在操作系统切换任务让其它程序变为活跃状态时阻止本引擎抓取(grab)鼠标光标。调用irr::IrrlichtDevice::yield()能够在窗口变成非活跃状态时避免那個忙碌的事件循环吃光所有CPU 周期。

int lastFPS = -1;

while(device->run())

{

if (device->isWindowActive())

{

driver->beginScene(true, true, video::SColor(255,200,200,200));

smgr->drawAll();

driver->endScene();

int fps = driver->getFPS();

if (lastFPS != fps)

{

core::stringw str = L"Irrlicht Engine - Quake 3 Map example [";

str += driver->getName();

str += "] FPS:";

str += fps;

device->setWindowCaption(str.c_str());

lastFPS = fps;

}

}

else

device->yield();

}

最后,删除Irrlicht 设备。

device->drop();

return 0;

}

完咯。编译,再在程序里漫游吧。

Your opinions
Your name:Email:Website url:Opinion content:
- no title specified

HxLauncher: Launch Android applications by voice commands

 
Recent comments
2017年4月~2019年4月垃圾短信排行榜Posted at:Thu Sep 26 04:51:48 2024
Qt5.7文档翻译:QWebEngineCookieStore类,QWebEngineCookieStore ClassPosted at:Fri Aug 11 06:50:35 2023盲盒kill -9 18289 Grebe.20230517.211749.552.mp4