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

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

 

Irrlicht引擎手册示例(二):Quake3Map!_第1张图片

让我们开始吧

 

 

 首先让我们像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;
}
就是这样编译并测试一下这个程序吧
 
 

你可能感兴趣的:(优化,vector,video,引擎,编译器,Direct3D)