Irrlicht学习笔记(2)--quake3map
2016-04-22 21:52
309 查看
1.这个例子设计内容:
1.加载quake3map,
2.为最优化渲染速度创建一个场景节点,
3.创建可交互的摄像机.
2.加载quake3map
1)quake3map被放在一个map-20kdm2.pk3的压缩包中,需要加载压缩包到文件系统,
然后直接通过名字获得map.
irr::io::IFileSystem()->addZipFileArchive("../media/map-20kdm2.pk3");
这个函数内部是通过下列函数实现其功能的:
函数说明:
irr::io::IFileSystem()->getFileArchive(
const path& file,/*文件名*/
bool ignorCase = true,/*true:加载文档后,访问内部不需要写全名字*/
bool ignorPaths = true,/*true:加载文档后,访问内部不需要写全部路径*/
E_FILE_ARCHIVE_TYPE archiveType = EFAT_UNKNOWN,/*文档格式*/
const core::stringc& password= " "/*密码*/
);
这个函数将文档加载进文件系统,加载后,irrlicht引擎将直接从文档中搜索需要的文件,
我们用到的.pk3事实上是ZIP文件格式的,它内部调用为device->getFileArchive(filename,true,true,EFAT_ZIP);
getFIleArchive函数可以加载ZIP,PAK,TAR,PNK,和文件夹形式的文档,
我们可以编写对自己的文档类型编相应fileloader,
只需要:
1.继承IArchiveLoader 类;
2.写相应的方法;
3.传递一个instance到core::array<IArchiveLoader*> ArchiveLoader;
最后一步调用函数:void addArchiveLoader(IArchiveLoader* loader);
irrlicht支持AES加密的zip文件和高压的文件lzma,bzip2.
3.加载地图模型
1)然后从文件系统加载需要的模型文件,将地图看作是只有一帧的动画,用scene::IAnimatedMesh:
scene::IAnimatedMesh*mesh = smgr->getMesh("20kdm2.bsp");
2)然后将mesh绑定到某个mesh场景节点上.
原来的方法:
node = smgr->addMeshSceneNode(mesh->getMesh(0));
为了提高渲染效率,我们将八叉树来管理mesh:
node = smgr->addOctreeSceneNode(
mesh->getMesh(0),/*返回的是一个指针:IMesh* */
0,
-1,
1024);
函数说明:
IMeshSceneNode* addOctreeSceneNode(
IMesh* mesh,/*这个节点需要的所有网格信息的地址*/
ISceneNode* parent =0,/*八叉树父节点*/
s32 id=-1,/*节点的唯一id*/
s32 minimalPolysPerNode = 256,/*每个八叉树节点的最小面数,在小就不可分了*/
bool alsoAddIfMeshPointerZero =false/*false:如果mesh为0就不分配节点*/
);
4.为节点设置属性
载入 地图后,需要对其进行属性设置:
比如位置,缩放,旋转,方法都在irr::scene::ISceneNode中:
irr::scene::ISceneNode::setPosition(),
irr::scene::ISceneNode::setRotationi(),
irr::scene::ISceneNode::setScale();
比如我们设置坐标:
node->setPosition(core::vector3df(-1300,-144,-1249));
5.设置像机
现在地图已经在场景的何时位置了,但是运行了之后看不到它,因为还没有设置摄像机.
使用可交互的摄像机.
比如Maya中的: smgr->addCameraSceneNodeMaya();
或者FPS游戏中: smgr->addCameraSceneNodeFPS();
现在运行就看得到了,不过中间有个鼠标太碍眼,需要隐藏掉.
方法在irr::gui::ICursorControl中,
通过irr::IrrlichtDevice获得irr::gui::ICursorControl对象,然后调用它的方法:
device->getCursorControl()->setVisible(false);
6.添加FPS显示
最后我们在窗口标题栏添加额外的信息:
渲染驱动选择和当前fps
显示结果形如:窗口名字 [渲染设备]FPS.***
获得当前fps:通过irr:IVideoDriver::getFPS()获得当前fps,这个函数是每秒返回一次fps,
所以为了未更新就不重新显示,我们添加一个标记外部lastFPS,保存上一秒的fps:
while外:int lastFPS = -1;//需要初始化
int fps = driver->getFPS();
if(lastFPS!=fps)
{
core::stringw str = L"quake3 map ]";//窗口名字
str+=driver->getName();//渲染器
str+="] FPS":
str+=fps;//fps
//改变窗体的标题
driver->setWindowCaption(str.c_str());
lastFPS= fps;//记录
}
7详细代码:
1.加载quake3map,
2.为最优化渲染速度创建一个场景节点,
3.创建可交互的摄像机.
2.加载quake3map
1)quake3map被放在一个map-20kdm2.pk3的压缩包中,需要加载压缩包到文件系统,
然后直接通过名字获得map.
irr::io::IFileSystem()->addZipFileArchive("../media/map-20kdm2.pk3");
这个函数内部是通过下列函数实现其功能的:
函数说明:
irr::io::IFileSystem()->getFileArchive(
const path& file,/*文件名*/
bool ignorCase = true,/*true:加载文档后,访问内部不需要写全名字*/
bool ignorPaths = true,/*true:加载文档后,访问内部不需要写全部路径*/
E_FILE_ARCHIVE_TYPE archiveType = EFAT_UNKNOWN,/*文档格式*/
const core::stringc& password= " "/*密码*/
);
这个函数将文档加载进文件系统,加载后,irrlicht引擎将直接从文档中搜索需要的文件,
我们用到的.pk3事实上是ZIP文件格式的,它内部调用为device->getFileArchive(filename,true,true,EFAT_ZIP);
getFIleArchive函数可以加载ZIP,PAK,TAR,PNK,和文件夹形式的文档,
我们可以编写对自己的文档类型编相应fileloader,
只需要:
1.继承IArchiveLoader 类;
2.写相应的方法;
3.传递一个instance到core::array<IArchiveLoader*> ArchiveLoader;
最后一步调用函数:void addArchiveLoader(IArchiveLoader* loader);
irrlicht支持AES加密的zip文件和高压的文件lzma,bzip2.
3.加载地图模型
1)然后从文件系统加载需要的模型文件,将地图看作是只有一帧的动画,用scene::IAnimatedMesh:
scene::IAnimatedMesh*mesh = smgr->getMesh("20kdm2.bsp");
2)然后将mesh绑定到某个mesh场景节点上.
原来的方法:
node = smgr->addMeshSceneNode(mesh->getMesh(0));
为了提高渲染效率,我们将八叉树来管理mesh:
node = smgr->addOctreeSceneNode(
mesh->getMesh(0),/*返回的是一个指针:IMesh* */
0,
-1,
1024);
函数说明:
IMeshSceneNode* addOctreeSceneNode(
IMesh* mesh,/*这个节点需要的所有网格信息的地址*/
ISceneNode* parent =0,/*八叉树父节点*/
s32 id=-1,/*节点的唯一id*/
s32 minimalPolysPerNode = 256,/*每个八叉树节点的最小面数,在小就不可分了*/
bool alsoAddIfMeshPointerZero =false/*false:如果mesh为0就不分配节点*/
);
4.为节点设置属性
载入 地图后,需要对其进行属性设置:
比如位置,缩放,旋转,方法都在irr::scene::ISceneNode中:
irr::scene::ISceneNode::setPosition(),
irr::scene::ISceneNode::setRotationi(),
irr::scene::ISceneNode::setScale();
比如我们设置坐标:
node->setPosition(core::vector3df(-1300,-144,-1249));
5.设置像机
现在地图已经在场景的何时位置了,但是运行了之后看不到它,因为还没有设置摄像机.
使用可交互的摄像机.
比如Maya中的: smgr->addCameraSceneNodeMaya();
或者FPS游戏中: smgr->addCameraSceneNodeFPS();
现在运行就看得到了,不过中间有个鼠标太碍眼,需要隐藏掉.
方法在irr::gui::ICursorControl中,
通过irr::IrrlichtDevice获得irr::gui::ICursorControl对象,然后调用它的方法:
device->getCursorControl()->setVisible(false);
6.添加FPS显示
最后我们在窗口标题栏添加额外的信息:
渲染驱动选择和当前fps
显示结果形如:窗口名字 [渲染设备]FPS.***
获得当前fps:通过irr:IVideoDriver::getFPS()获得当前fps,这个函数是每秒返回一次fps,
所以为了未更新就不重新显示,我们添加一个标记外部lastFPS,保存上一秒的fps:
while外:int lastFPS = -1;//需要初始化
int fps = driver->getFPS();
if(lastFPS!=fps)
{
core::stringw str = L"quake3 map ]";//窗口名字
str+=driver->getName();//渲染器
str+="] FPS":
str+=fps;//fps
//改变窗体的标题
driver->setWindowCaption(str.c_str());
lastFPS= fps;//记录
}
7详细代码:
#include <iostream> #include <irrlicht.h> using namespace irr; #ifdef _IRR_WINDOWS_ #pragma comment(lib, "irrlicht.lib") //#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") #endif void mySetCreatParamters(SIrrlichtCreationParameters* cp); void mySetDeviceType(video::E_DRIVER_TYPE* drivertype); int main(int argc, char** argv) { //我们使用其他方式创建一个IrrlichtDevice SIrrlichtCreationParameters cParam; //mySetDeviceType(&cParam.DriverType);//2.用到的 mySetCreatParamters(&cParam); IrrlichtDevice *device = //1. createDevice(video::EDT_OPENGL, core::dimension2d<u32>(720, 455), 32,false, true, false, 0); //2. createDevice(cParam.DriverType, core::dimension2d<u32>(800, 600)); createDeviceEx(cParam);//3. if (!device) return 1; device->setWindowCaption(L"quake3 map"); video::IVideoDriver *driver = device->getVideoDriver(); scene::ISceneManager *smgr = device->getSceneManager(); gui::IGUIEnvironment *guiev = device->getGUIEnvironment(); //为了显示quake3 map,我们要加载它,而其被压缩在map-20kdm2.pk3中, //所以先将压缩包加载到文件系统 //实际调用device->getFileArchive(filename,true,true,EFAT_ZIP); device->getFileSystem()->addZipFileArchive("../media/map-20kdm2.pk3"); //将地图当作一帧动画加载 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)); } //通过irr::scene::ISceneNode层的方法对node进行属性调整 //位置:irr::scene::ISceneNodeirr::scene::ISceneNode::setPosition() //旋转:irr::scene::ISceneNode::setRotation() //缩放:irr::scene::ISceneNode::setScale(); if (node) { node->setPosition(core::vector3df(-1300, -144, -1249)); // node->setRotation(core::vector3df(0, 0, 0)); // node->setScale(core::vector3df(1, 1, 1)); } //万事俱备,只需要添加一台摄像机, //maya型的摄像机:irr::scene::ISceneManager::addCameraSceneNodeMaya() //FPS:irr::scene::ISceneManager::addCameraSceneNodeFPS() smgr->addCameraSceneNodeFPS(); //隐藏鼠标:irr::IrrlichtDevice::ICursorControl device->getCursorControl()->setVisible(false); int lastFPS = -1; while (device->run()) { if (device->isWindowActive()) { driver->beginScene(true, true, video::SColor(255, 100, 101, 140)); smgr->drawAll(); guiev->drawAll(); driver->endScene(); int fps = driver->getFPS(); if (lastFPS != fps) { core::stringw str = L"quake3 map ["; str += driver->getName(); str += "]FPS.", str += fps; device->setWindowCaption(str.c_str()); lastFPS = fps; } } else //防止一直渲染占用过多cpu device->yield(); } device->drop(); return 0; } void mySetCreatParamters(SIrrlichtCreationParameters* cp) { std::cout << "Please select the driver you want:\n" "(a) opengl\n(b)Direct3D 9.0c\n(c)Direct3D 8.1\n" "(d)Burning's Software render\n(e)Software Renderer\n" "(f)NullDevice\n(otherKey exit\n\n"; char i; std::cin >> i; switch (i) { case 'a': cp->DriverType = video::EDT_OPENGL; break; case 'b': cp->DriverType = video::EDT_DIRECT3D9; break; case 'c': cp->DriverType = video::EDT_DIRECT3D8; break; case 'd': cp->DriverType = video::EDT_BURNINGSVIDEO; break; case 'e': cp->DriverType = video::EDT_SOFTWARE; break; default: exit(1); } cp->DeviceType = EIDT_BEST; cp->WindowSize = core::dimension2d<u32>(800, 600); cp->Bits = 16; cp->ZBufferBits = 16; cp->Fullscreen = false; cp->Stencilbuffer = false; cp->Vsync = false; cp->AntiAlias = 0; cp->WithAlphaChannel = false; cp->Doublebuffer = true; cp->IgnoreInput = false; cp->Stereobuffer = false; cp->HighPrecisionFPU = false; cp->EventReceiver = 0; cp->WindowId = 0; cp->LoggingLevel = ELL_INFORMATION; } void mySetDeviceType(video::E_DRIVER_TYPE* drivertype) { std::cout << "Please select the driver you want:\n" "(a) opengl\n(b)Direct3D 9.0c\n(c)Direct3D 8.1\n" "(d)Burning's Software render\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; default: exit(1); } }
相关文章推荐
- elgg添加网页方法
- 构建之法阅读笔记04
- MapReduce输入格式
- Problem1020
- 深夜课堂:(function($){})(jQuery)函数以及其它jQ函数
- 编写一个程序,不断要求用户输入两个数,直到其中一个数为0
- BestCoder-Machine(三进制-彩灯变换)
- 下载Youtube视频只有2个步骤
- Android 拦截修改电话号码
- Swing显示边框效果总结
- nand flash的读写操作
- Web学习之css
- Kali运行wireshark报错信息处理
- POJ 1661
- 汇编十个数字分别相乘再相加
- Educational Codeforces Round 12
- 项目模块场景描述
- 冲刺第五天
- [参考]spring整合redis!
- Python中Matplotlib绘图