game-programing

~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;
    }

 

~Irrlicht Tutorial3~ The basic animatoring....

posted on 01 Dec 2008 17:26 by apemon-chan  in game-programing

            จากคราวที่แล้วที่เราได้สร้างscenenodeแบบง่ายๆกันไปแล้ว คราวนี้เราจะมาลองใส่animatorอย่างง่ายๆ
    ให้กับscenenodeงับ

            มาเริ่มที่แบบแรกanimatorที่basicสุด ก็คือวิ่งมันตรงๆนี่แหละ ถ้าพร้อมแล้วสร้างscenenodeมา1อันก่อนเลย
    (จะไม่อธิบายถึงส่วนheaderกะการสร้างscenenodeเน้อ เพราะได้กล่าวถึงมันไปแล้ว)

            scene::ISceneNode* node=smgr->addSphereSceneNode();
            node=smgr->addSphereSceneNode();
            node->setPosition(core::vector3df(0,0,30));
            node->setMaterialFlag(video::EMF_LIGHTING,false);
            node->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));

            อันนี้ก็สร้างทรงกลม1อัน

            scene::ISceneNodeAnimator* anim=0;

            สร้างISceneNodeAnimatorขึ้นมา

            anim=smgr->createFlyStraightAnimator(
            core::vector3df(0,0,30),
            core::vector3df(50,0,30),
            6000,true);

            สร้างFlyStraightAnimator(ก็คือวิ่งตรงๆนะแหละ) โดย
            core::vector3df(0,0,30) หมายถึงจุดเริ่มต้น
            core::vector3df(50,0,30) จุดหมายปลายทาง
            6000 นี่คือเวลาที่ใช้(millisecond)
            true อันนี้กำหนดว่าให้มันloopหรือเปล่า ถ้าต้องการเล่นรอบเดียวจบก็setเป็นfalse

            node->addAnimator(anim);         

            แปะanimatorลงไปในnode

            เท่านี้ก็เรียบร้อย ลองrunดูจะเห็นบอลวิ่งแล้วละน่ะ

            ต่อมาลองanimatorพื้นฐานอีกอันดู อันนี้คือหมุนไปรอบๆ

            scene::ISceneNode* node2;
            node2=smgr->addCubeSceneNode();
            node2->setPosition(core::vector3df(-30,0,30));
            node2->setMaterialFlag(video::EMF_LIGHTING,false);
            node2->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));

            สร้างหนูทดลอง ในที่นี้คือกล่องใบนึง

            anim=smgr->createFlyCircleAnimator(
            core::vector3df(-15,0,15),
            15,0.001,
            core::vector3df(1,0,0));

            สร้างFlyCircleAnimator(คือโคจรรอบๆ) โดย
            core::vector3df(-15,0,15) จุดศูนย์กลาง
            f32 15 รัศมี
            f32 0.001 ความเร็ว
            core::vector3df(1,0,0) ประมาณว่าทิศทางวงโคจร(ลองปรับเล่นดู)

            node2->addAnimator(anim);

            แปะanimatorเข้ากับscenenode

            anim->drop();

            หมดประโยชน์ก็โละทิ้ง เพื่อเคลียร์พื้นที่(ใจร้ายจัง)

            ก็เป็นอันเสร็จเรียบร้อยงับ ถ้าจะให้เห็นชัดก็สร้างscenenodeไปวางจุดcenterของวงโคจรก็ได้

                                    

            อันนี้codeแบบเต็มๆงับ

     #include <irrlicht.h>
     using namespace irr;
    #pragma comment(lib, "Irrlicht.lib")
     int main(){
    IrrlichtDevice *device =
    createDevice(video::EDT_DIRECT3D9, core::dimension2d<s32>(640, 480));

     if (device == 0)
        return 1;
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();    
    //create scenenode
    scene::ISceneNode* node;
    scene::ISceneNode* node2;
   
scene::ISceneNode* node3;//อันนี้ใส่ไว้ตรงจุดcenterของวงโคจรnode2
    node=smgr->addSphereSceneNode();
    node->setPosition(core::vector3df(0,0,30));
    node->setMaterialFlag(video::EMF_LIGHTING,false);
    node->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));
    node2=smgr->addCubeSceneNode();
    node2->setPosition(core::vector3df(-30,0,30));
    node2->setMaterialFlag(video::EMF_LIGHTING,false);
    node2->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));

    node3=smgr->addSphereSceneNode();
    node3->setPosition(core::vector3df(-15,0,15));
    node3->setMaterialFlag(video::EMF_LIGHTING,false);
    node3->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));
    //create animator
    scene::ISceneNodeAnimator* anim=0;
    anim=smgr->createFlyStraightAnimator(
            core::vector3df(0,0,30),
            core::vector3df(50,0,30),
            6000,true);
   
node->addAnimator(anim);
    anim=smgr->createFlyCircleAnimator(
            core::vector3df(-15,0,15),
            15,0.001,
            core::vector3df(1,0,0));
    node2->addAnimator(anim);
    anim->drop();

    //create camerascenenode
    scene::ICameraSceneNode* cam;
    cam=smgr->addCameraSceneNodeFPS();
    cam->setPosition(core::vector3df(36,4,-49));

    while(device->run())
   {
       driver->beginScene(true, true, video::SColor(0,200,200,200));
       smgr->drawAll();
       driver->endScene();
   }
   device->drop();
   return 0;
   }

 

 

~Irrlicht Tutorial2~ The SceneNoding....

posted on 17 Nov 2008 18:24 by apemon-chan  in game-programing

            ก่อนที่จะเริ่มในคราวนี้ก็ขอแนะนำบล็อกที่เป็นประโยชน์ต่อการศึกษาengineตัวนี้นะงับ http://afterzeroo.exteen.com ซึ่งเป็นบล็อกที่มีเนื้อหาดีมากงับ ลองเข้าไปดูกันนา

            วันนี้เราจะมาพูดถึงSceneNodeกัน อะไรคือSceneNodeเดี๋ยวเราจะได้รู้กันงับ SceneNode พูกง่ายๆตาม
ประสาnoobก็คือobjectหนึ่งๆบนโลกนะงับเช่น ลูกบอลลูกหนึ่ง,กล่อง หรือ ปราสาทหลังหนึ่ง,เกรียนตัวหนึ่ง หรือแม้แต่มุมกล้องที่เราใช้ ประมาณนี้นักแล

            สำหรับtutorialนี้เราจะมาสร้างSceneNodeง่ายๆกันคับ ว่าแล้วเราก็ลองไปเริ่มกันเลยยยยย......

            ก่อนอื่นก็หยิบงานคราวที่แล้วมา่ปัดฝุ่นแล้วทำต่อนะงับ จากที่แล้วหลังจากที่เราได้สร้างSceneManager คราวนี้เราจะได้ใช้ประโยชน์จากมันงับ โดยเริ่มจากการสร้างSceneNodeขึ้นมาก่อนงับ

                    scene::ISceneNode* node;

            สร้างSceneNodeที่มีชื่อว่าnodeงับ(เล่นง่ายไหมล่ะ)

            ต่อมาอยากจะเอาลูกบอลหรือกล่องก่อนล่ะ งั้นเราขอเอาลูกบอลก่อนละกันงับ

                   node=smgr->addSphereSceneNode();

            สร้างเสร็จแล้ว แต่ยังไม่ได้กำหนดตำแหน่งที่อยู่ให้มันเลยอ่ะ งั้นเรามากำหนดตำแหน่งให้มันหน่อยละกัน

                   node->setPosition(core::vector3df(0,0,30));

           อันนี้กำหนดตำแหน่งให้มันอยู่บนระนะทางแกนZไปประมาณ30งับ สำหรับการสร้างวัตถุ3มิติ เวลาเราอ้างอิงพิกัดต่างๆเราจะอ้างอิงเป็นvectorนะงับ ไม่ใช่กำหนดpixelแบบใน2มิติ 

           ตอนนี้ถ้าลองrunดูจะพบว่ามันเป็นก้อนกลมๆสีดำนะงับ เราจะมาแปะtextureให้มันซะหน่อยงับ

                  node->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));

           ตอนนี้เราได้ปะtextureลงไปแล้ว(ไฟล์พวกนี้หาได้จากโฟล์เดอร์mediaที่อยู่ในโฟล์เดอร์irrlichtนะงับ ลองหาดูแล้วก็อบโฟล์เดอร์mediaมาไว้ในโฟล์เดอร์งานของเรางับ) ลองrunดู อ้ายทำไมมันยังดำเมี่ยมอยู่ฟระ
ที่เป็นแบบนี้เพราะเรายังไม่ได้ปิดการคำนวณแสงมันงับ ว่าแล้วก็มันมันซะ

                 node->setMaterialFlag(video::EMF_LIGHTING,false);

           ยัง มันยังไม่จบยังไม่ได้ใส่มุมกล้องลงไปเลย ว่าแต่จะเอามุมกล้องแบบmayaหรือfpsดีล่ะ

                smgr->addCameraSceneNodeFPS();

           ถ้าจะใช้แบบmayaก็ smgr->addCameraSceneNodeMaya();
           ทีนี้ลองrunดูก็น่าจะเห็นบอลมันอยู่ตรงกลางแล้วเน้อ ต่อมาเราจะมาสร้างกล่องกันล่ะ

               scene::ISceneNode* node2;
               node2=smgr->addCubeSceneNode();
               node2->setPosition(core::vector3df(-30,0,30));
               node2->setMaterialFlag(video::EMF_LIGHTING,false);
               node2->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));

          อันนี้ก็ล้อเลียนของเดิมนะงับ แต่เราจะมาปู้นี้ปู้ยำกับเจ้ากล่องนี้ด้วย2คำสั่งนี้งับ

             node2->setRotation(core::vector3df(10,20,30));
             node2->setScale(core::vector3df(2,1,1));

          อันแรกทำให้กล่องมันวางเอียงๆ ส่วนอันที่2ทำให้กล่องมีรูปทรงตามscaleมันในทีนี้ เราให้มันขยายความยาวด้านแกนxให้เป็น2เท่างับ ลองแก้ค่าตัวเลขเล่นๆน่ะ เราจะได้กล่องรูปทรงประหลาดออกมา

          รูปก็ประมาณนี้งับ

                                  

            ส่วนอันนี้ก็codeทั้งหมดงับ

#include <irrlicht.h>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
int main(){
    IrrlichtDevice *device =
    createDevice(video::EDT_DIRECT3D9,
    core::dimension2d<s32>(640,480));

    if (device == 0)
        return 1;
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
   
scene::ISceneNode* node;
    scene::ISceneNode* node2;
    node=smgr->addSphereSceneNode();
    node->setPosition(core::vector3df(0,0,30));
    node->setMaterialFlag(video::EMF_LIGHTING,false);
    node->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));
    node2=smgr->addCubeSceneNode();
    node2->setPosition(core::vector3df(-30,0,30));
    node2->setRotation(core::vector3df(10,20,30));
    node2->setScale(core::vector3df(2,1,1));
    node2->setMaterialFlag(video::EMF_LIGHTING,false);
    node2->setMaterialTexture(0,driver->getTexture("media/wall.bmp"));

    smgr->addCameraSceneNodeFPS();
  
while(device->run())
{
  driver->beginScene(true, true, video::SColor(0,200,200,200));
  smgr->drawAll();
  driver->endScene();
  }
 device->drop();
  return 0;
}

 

Favourites