Irrlicht引擎手册示例(二):Quake3Map!

     本教程演示了如何把一个引擎加载雷神之锤3地图进引擎,创建一个用来优化渲染速度的SceneNode和如何创建一个用户控制的摄像机。请注意,在开始本教程之前你应该先了解该引擎的基础知识,如果你还没有了解的话,请先查看第一个教程,1.HelloWorld。
这个例子的结果会是这样的:

 

让我们开始吧

 

 

 首先让我们像helloworld的例子一样:我们包含Irrlicht的头文件和一个额外的文件以便能够使用控制台的一些程序类。

正如已经在HelloWorld例子写的,在Irrlicht引擎中所有类都包含在命名空间"IRR"中。为了不在每个类名前加 irr:: ,我们在开始处告诉编译器包含irr命名空间。

在这里面已包含了'core', 'scene', 'video', 'io' 和 'gui'五个子命名空间,所以我们不

需要像helloworld一样包含这五个命名空间,当然如果你喜欢也可以像之前例子一样。就像以下代码:

using namespace irr;

接着,为了使我们的程序可以使用Irrlicht的DLL文件,我们需要连接Irrlicht.lib库。我们可以在项目设置中设置此选项,但我们使用pragma comment 预处理将会更加简单:

#pragma comment(lib, "Irrlicht.lib")

好了,接下来我们使用main() 方法作为开始,这里不使用WinMain(),因为main更精短些。

int main()
{

像HelloWorld例子中一样,我们用createDevice()创建一个IrrlichtDevice。现在不同的是,我们要求用户选择使用硬件加速驱动。当然软件设备也可以画一个巨大的“雷神之锤3:地图但它太慢。不过这里为了学习,我们提供了可以自己选择的方法。

// 要求用户选择驱动程序
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;
 


 

 

获取指向视频驱动和场景管理的指针,这样我们就不需要总是写device->getVideoDriver() 和device->getSceneManager()。

 
 
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();

 

要显示雷神之锤3地图,我们首先需要加载它。雷神之锤3地图被打包成.pk3格式文件,你可以看成像.zip文件打包一样。

现在我们把.pk3文件加入我们的文件系统,加入之后,我们就能够像存储在硬盘上一样从打包文件中读取到地图文件。

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

现在,我们可以调用getMesh()加载网格。我们返回一个IAnimatedMesh指针。如你所知,雷神之锤3:地图不是真正的动画,它们只是一些附加材质的静态几何块。

因此,IAnimated的网格组成,只有一帧。所以我们将通过quake level来获取“动画”的“第一帧”并且使用addOctTreeSceneNode()创建一个OctTree 的场景节点。

OctTree(八叉树)通过只绘制目前可见的几何形状来优化场景。如果这里使用AnimatedMeshSceneNode替换OctTree 的话,引擎将没有任何优化的绘制完整的网格几何。

试试看:将addOctTreeSceneNode 替换成addAnimatedMeshSceneNode ,然后通过视频驱动比较一下两者(这里可以通过IVideoDriver 类的一个方法 getPrimitiveCountDrawed() 来做到),请注意Octree 只有当绘制由很多几何体组成巨大网格时才能起到作用。

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

if (mesh)
    node = smgr->addOctTreeSceneNode(mesh->getMesh(0));

由于该网格不是以(0,0,0)为原点的,我们这里把它转换一下。

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

现在我们只需要一个摄像头用来看雷神之锤3的地图。我们要创建一个用户控制的摄像机。Irrlicht引擎提供了不同种类的。例如Maya摄像头,按下鼠标左键可以控制相机旋转,按下两个按钮时放大,按下鼠标右键移动。这个可以对通过addCameraSceneNodeMaya()创建。但在这个例子中,我们要创建一个像在第一人称射击游戏(FPS)中的摄像头行为:

smgr->addCameraSceneNodeFPS();

鼠标光标需要隐藏,所以这里我们把它设置成不可见。

  
  
device->getCursorControl()->setVisible(false);
好了,我们完成了所需的所有事情,现在我们要把它画出来。然后我们把每一帧的FPS信息画在窗口标题上。这里'if (device->isWindowActive())' 是可选的,不过当为了防止当其它程序被激活切换任务时,引擎渲染改变鼠标光标的位置是就要加上了。
 
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(); //irr::IrrlichtDevice::yield()将避免当窗口不活跃时,繁忙的循环,吃掉所有CPU周期。
 }

  最后,删除Irrlicht的设备。
  
  
  device->drop();
  return 0;
}
就是这样。编译并测试一下这个程序吧。
 
 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值