~Irrlicht Tutorial4~ LoadMap and Modeling...
posted on 08 Dec 2008 16:51 by apemon-chan in game-programing
ในคราวนี้เราจะมาload mapเข้าแผนที่กันงับ หลังจากที่คราวที่แล้วเราได้สร้างanimatorอย่างง่ายๆ
แล้ว โดยไฟล์ที่irrlicht supportมีดังนี้(อ้างอิงจากwikiนะ)
Animated and Rigged:
B3D files (.b3d)
Milkshape (.ms3d)
Microsoft DirectX (.x) (binary & text)
Animated only:
Quake 2 models (.md2)
Quake 3 models (.md3)
Static:
3D Studio meshes (.3ds)
Alias Wavefront Maya (.obj)
Cartography shop 4 (.csm)
COLLADA (.xml, .dae)
DeleD (.dmf)
FSRad oct (.oct)
Irrlicht scenes (.irr)
My3DTools 3 (.my3D)
OGRE meshes (.mesh)
Pulsar LMTools (.lmts)
Quake 3 levels (.bsp)
โดยเราจะเริ่มโหลดmapเข้ามาในงานเรานะงับ โดยmapที่เราจะใช้นั้นเป็นmapของเกมquake3โดยจะอยู่
ในโฟล์เดอร์mediaที่อยู่ในโฟล์เดอร์irrlichtนะงับ ลองหาดูแล้วก็อบโฟล์เดอร์mediaมาไว้ในโฟล์เดอร์งานของ
เรางับ ไฟล์มันจานามสกุลpk3ซึ่งเราสามารถแกะมันด้วยwinrarงับ ดังนั้นเวลาเราจะโหลดmapนี้ต้องอ่านมัน
ในรูปแบบไฟล์ที่ถูกอัดzipงับ
device->getFileSystem()->addZipFileArchive("media/map-20kdm2.pk3");
อ่านไฟล์ที่ถูกอัดzipงับ
scene::IAnimatedMesh* mesh=0;
mesh=smgr->getMesh("20kdm2.bsp");
สร้างIAnimatedMesh โดยตัวนี้จะเหมือนกับเป็นตัวโหลดโมเดล ในขณะที่scenenodeนั้นใช้ควบคุม
วัตถุนั้น
สำหรับคำสั่งข้างบนนั้นคือสั่งให้โหลดโมเดล20kdm2.bspมาใส่ในIAnimatedMesh (ไฟล์
20kdm2.bspนี้จะอยู่ในmap-20kdm2.pk3 ลองแกะดูเน้อ)
scene::ISceneNode* map=0;
map=smgr->addOctTreeSceneNode(mesh->getMesh(0));
สร้างnodeมาเก็บควบคุมmapโดยnodeที่ใช้คราวนี้คือOctTreeSceneNodeซึ่งเป็นnodeอีกประเภท
หนึ่งที่จะมาว่ากันทีหลัง
map->setPosition(core::vector3df(-1300,-144,-1249));
อันนี้setตำแหน่งของmapเรางับ(ให้มองว่าmapเหมือนก้อนโมเดลใหญ่ๆน่ะ)
เสร็จแล้วก็add camerascenenodeแล้วก็อย่าลืมmain loop เมื่อเสร็จสมบูรณ์แล้วลองรันดูจะได้ผลดัง
ภาพงับ
ตอนนี้ก็บรรลุจุดประสงค์ไป1อย่าง ต่อมาเราจะโหลดโมเดลกันงับ
scene::IAnimatedMeshSceneNode* anms =0;
mesh=smgr->getMesh("media/sydney.md2");
smgr->addAnimatedMeshSceneNode(mesh);
เห็นถึงความแตกต่างยังงับระหว่างmapกับmodel
-modelที่เราโหลดมาเป็นไฟล์md2ซึ่งมีการเคลื่อนไหว ในขณะที่mapเป็นbspซึ่งมันstatic
-ดังนั้นในการเรียกใช้meshจึงไม่เหมือนกัน อย่างmapนั้นเราใช้mesh->getMesh(0) ซึ่ง
มันเป็นIStaticMesh ในขณะที่modelเราใช้meshตรงๆเลย(อย่าลืมว่าเดิมทีเราประกาศให้มัน
เป็นIAnimatedMesh
-OctTreeSceneNodeกับAnimatedMeshSceneNode นั้นไม่เหมือนกันน่ะ OctTree
คือAnimatedที่ลดการวาดรูปทรง ซึ่งmapนี่คงไม่น่ามีการเปลี่ยนแปลงตลอดเวลา(แต่มันมีขนาดใหญ่)
ดังนั้นเราจึงใช้OctTreeสำหรับวัตถุใหญ่ๆที่ไม่ค่อยมีการanimate ส่วนAnimatedนี่ก็ใช้กับวัตถุที่มี
animateทั่วๆไปงับ
anms->setMaterialTexture(0,driver->getTexture("media/sydney.bmp"));
anms->setMaterialFlag(video::EMF_LIGHTING,false);
anms->setPosition(core::vector3df(114,-50,96));
anms->setScale(core::vector3df(2,2,2));
อันนี้ก็โหลดtexture,แล้วก็ตั้งค่าปกติ(ถ้าไม่getลองดูในtutorialที่ผ่านๆมาดู)
anms->setAnimationSpeed(30);
anms->setFrameLoop(200,400);
อันนี้คือsetว่าจะให้animateเร็วขนาดไหนโดยตัวเลขในวงเล็บคือframe per sec
ส่วนบรรทัดต่อมาคือจะให้เลือกเล่นช่วงที่เฟรมที่เราต้องการ โดยในตัวอย่างคือเริ่มที่200จบที่400
แล้วก็เล่นซำ้ช่วงนี้เรื่อยๆ ลองrunดูก็จะได้ผลดังภาพ
codeตัวอย่างงับ
//header
#include <irrlicht.h>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
//main
int main(){
IrrlichtDevice *device =createDevice(
video::EDT_DIRECT3D9, core::dimension2d<s32>(640, 480));
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
//load mesh for map
device->getFileSystem()->addZipFileArchive("media/map-20kdm2.pk3");
scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
scene::ISceneNode* map = 0;
map = smgr->addOctTreeSceneNode(mesh->getMesh(0));
map->setPosition(core::vector3df(-1300,-144,-1249));
//setup camera
smgr->addCameraSceneNodeFPS();
//hide mouse cursor
device->getCursorControl()->setVisible(false);
//load model
mesh=smgr->getMesh("media/sydney.md2");
scene::IAnimatedMeshSceneNode* anms =
smgr->addAnimatedMeshSceneNode(mesh);
anms->setMaterialFlag(video::EMF_LIGHTING,false);
anms->setMaterialTexture(0,driver->getTexture("media/sydney.bmp"));
anms->setPosition(core::vector3df(114,-50,96));
anms->setScale(core::vector3df(2,2,2));
anms->setAnimationSpeed(30);
anms->setFrameLoop(200,400);
//main loop
while(device->run())
{
driver->beginScene(true, true, video::SColor(0,200,200,200));
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}