Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autor: Mariusz Klepaczko
Biblioteki C++

Duplikowanie modeli na scenie

[lekcja] Rozdział 6. Optymalizacja poprzez duplikowanie modeli i przykład zastosowania.

Duplikowanie Modeli Na Scenie

C/C++
#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;

#pragma comment(lib, "Irrlicht.lib")

int main()
{
    IrrlichtDevice * device = createDevice( EDT_OPENGL, core::dimension2d < s32 >( 640, 480 ),
    32, false, false, false, 0 );
   
    video::IVideoDriver * video = device->getVideoDriver();
    scene::ISceneManager * menage = device->getSceneManager();
    scene::ICameraSceneNode * kam = menage->addCameraSceneNodeFPS( 0, 100.0f, 60.0f );
    device->getCursorControl()->setVisible( false );
    kam->setPosition( core::vector3df( 0, 0, - 20 ) );
    video->setTextureCreationFlag( video::ETCF_ALWAYS_32_BIT, true );
    //Zasięg pola widzenia kamery
    kam->setFarValue( 90000 );
    device->setWindowCaption( L"Powielanie modeli. Kurs Irrlicht, Mariusz Klepaczko dla ddt.pl" );
    //Wczytywanie modelu
    // _Stworzyliśmy "Węzeł" do którego będziemy wczytywać nasze pudełka
    scene::IAnimatedMeshSceneNode * node_pudlo = 0;
    scene::IAnimatedMesh * pudlo = menage->getMesh( "media/mesh/pudlo.mesh" );
    // Tworzymy materiał dla naszych pudełek
   
    video::SMaterial material_pierwszy; // Materiał pierwszy
    material_pierwszy.setTexture( 0, video->getTexture( "media/img/pud_2.png" ) );
    material_pierwszy.Lighting = false;
   
    video::SMaterial material_drugi; // Materiał drugi
    material_drugi.setTexture( 0, video->getTexture( "media/img/pudlo.png" ) );
    material_drugi.Lighting = false;
   
    video::SMaterial material_trzeci; // Materiał trzeci
    material_trzeci.setTexture( 0, video->getTexture( "media/img/pud_3.png" ) );
    material_trzeci.Lighting = false;
    //Powielamy pudło
   
    if( pudlo )
    {
        node_pudlo = menage->addAnimatedMeshSceneNode( pudlo );
        node_pudlo->setPosition( core::vector3df( 0, 0, 0 ) );
        node_pudlo->getMaterial( 0 ) = material_pierwszy;
       
        node_pudlo = menage->addAnimatedMeshSceneNode( pudlo );
        node_pudlo->setPosition( core::vector3df( 10, 0, 0 ) );
        node_pudlo->getMaterial( 0 ) = material_drugi;
       
        node_pudlo = menage->addAnimatedMeshSceneNode( pudlo );
        node_pudlo->setPosition( core::vector3df( - 10, 0, 0 ) );
        node_pudlo->setRotation( core::vector3df( 0, 0, 90 ) );
        node_pudlo->getMaterial( 0 ) = material_trzeci;
    }
   
    while( device->run() )
   
    {
        video->beginScene( true, true, video::SColor( 255, 0, 10, 200 ) );
        menage->drawAll();
        video->endScene();
    }
    device->drop();
    return 0;
}


Kod pochodzi z lekcji drugiej. Zostały jedynie dodane kilka linii kodu, o których poniżej mowa.

Do czego może się przydać duplikowanie modeli, odpowiedź jest oczywista. By nie obciążać komputera, gdyż my w ten sposób ustawiamy na naszej scenie, model który został już wczytany. Nie wczytujemy go ponownie do pamięci. Mało tego mamy nad nim władzę absolutną ;-) Ktoś by się mógł w tym momencie zastanawiać, o co chodzi z tą władzą. Odpowiedź jest prosta, każdy zduplikowany (powielony) model może posiadać własne parametry dla oświetlenia, mgły, może posiadać inną texture itp. Po co nam to? Już odpowiadam, dajmy na to że, tworzysz swoją grę i potrzebujesz wstawić kilkanaście drzew do ogrodu w którym rozgrywała by się jedna z akcji. To właśnie jest najlepsza okazja, by zastosować się do rad z tej lekcji, gdyż nie musisz pisać kolejnych linijek kodu, odpowiedzialnych za wczytywanie modelu i jego wyświetlanie. Przejdźmy do analizy kodu:

C/C++
// _Stworzyliśmy "Węzeł" do którego będziemy wczytywać nasze pudełka
scene::IAnimatedMeshSceneNode * node_pudlo = 0;
scene::IAnimatedMesh * pudlo = menage->getMesh( "media/mesh/pudlo.mesh" );

W pierwszej linii kodu utworzyliśmy nasz węzeł (node_pudlo) gdzie, będziemy przechowywać wszystkie dane dla naszego pudełka, np. dane dla materiału, textury, czy pudło ma być oświetlane itp.

W drugiej linii kodu wczytujemy do naszego managera (menage) obiekt, w tym wypadku jest to nasze pudełko. Proste, prawda, ale to jeszcze nie wszystko w następnej kolejności utworzymy materiały dla naszych pudełek.

C/C++
video::SMaterial material_pierwszy; // Materiał pierwszy
material_pierwszy.setTexture( 0, video->getTexture( "media/img/pud_2.png" ) );
material_pierwszy.Lighting = false;

video::SMaterial material_drugi; // Materiał drugi
material_drugi.setTexture( 0, video->getTexture( "media/img/pudlo.png" ) );
material_drugi.Lighting = false;

video::SMaterial material_trzeci; // Materiał trzeci
material_trzeci.setTexture( 0, video->getTexture( "media/img/pud_3.png" ) );
material_trzeci.Lighting = false;

Tu stworzyliśmy trzy materiały, tak aby każde pudełko wyglądało inaczej.  Pierwsza linia jest odpowiedzialna za przypisanie nazwy naszego materiału, który może następnie być użyty tyle razy, ile nam się podoba.

Druga linia kodu, to nic innego, jak załadowanie naszej textury i przypisanie jej do materiału o nazwie "material_pierwszy". Następna linia kodu, sprawdza czy dla materiału włączamy oświetlenie, false - nie, true - tak.

Ale pamiętajmy by oświetlenie dla materiału, używać tylko przy stworzonym świetle dynamicznym w innym wypadku obiekty będą czarne. No właśnie, kiedy dowiemy się coś o światełku, myślę że w następnej lekcji.

Oczywiście można też przypisać inne opcje dla materiału, ale nie o tym jest ta lekcja ;-). Następne linie kodu:

C/C++
if( pudlo )
{
    node_pudlo = menage->addAnimatedMeshSceneNode( pudlo );
    node_pudlo->setPosition( core::vector3df( - 10, 0, 0 ) );
    node_pudlo->setScale( core::vector3df( 1.5, 1.5, 1.5 ) );
    node_pudlo->setRotation( core::vector3df( 0, 0, 90 ) );
    node_pudlo->getMaterial( 0 ) = material_trzeci;
    material_trzeci.Lighting = false;

Pozwalają nam określić w jaki sposób pudło będzie wyświetlane. Pierwsza linia kodu powiadamia iż, chcemy wykorzystać nasze, wcześniej załadowane do pamięci pudełko (pudlo). Druga linia określa pozycje a, właściwie miejsce w którym będzie wyświetlane nasze pudełko w świecie 3d ( X, Y, Z ). Trzecia linia kodu nakazuje powiększyć nasze pudło do żądanych rozmiarów (przeskalowanie). Kolejna linia, odpowiada za obrót (setRotation). No i wreszcie nasz materiał, bo to właśnie piąta linia, odpowiada za nadanie obiektowi, wcześniej przygotowanego materiału. W tym wypadku jest to materiał trzeci. Pamiętajmy by nie mylić nazw, gdyż przy dużej liczbie materiałów, uwierzcie mi, można się pogubić. To tyle jeśli chodzi o dzisiejszą lekcję. Ale, mam dla was zadanie. Tak, dobrze widzisz. Postaraj się pozamieniać kolejność wyświetlania materiału na pudłach i pozmieniaj ich nazewnictwo, przemieść pudła tak, by pudło z texturą "ddt.pl" znalazło się w środku, a jedno z pudeł by znajdowało się bezpośrednio nad nim, z kolei drugie, tuż pod nim.
Powodzenia.

Materiały do pobrania

Pliki potrzebne do uruchomienia tej lekcji można pobrać z naszego repozytorium.
Poprzedni dokument Następny dokument
Dodawanie sceny Kurs New Curses, C++