您的位置:首页 > 其它

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详细代码:

#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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: