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

Dodawanie sceny

[lekcja] Rozdział 5. Wczytywanie sceny i jej wyświetlanie.

Dodawanie Sceny

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

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

// Tworzymy klase
class Klawisze
    : public IEventReceiver
{
public:
    virtual bool OnEvent( const SEvent & event )
    {
        //  Zapamiętuje położenie klawisza (klucza) (góra/dół)
        if( event.EventType == irr::EET_KEY_INPUT_EVENT )
             KeyIsDown[ event.KeyInput.Key ] = event.KeyInput.PressedDown;
       
        return false;
    }
   
    // Sprawdza czy klawisz (klucz) został użyty
    virtual bool IsKeyDown( EKEY_CODE keyCode ) const
    {
        return KeyIsDown[ keyCode ];
    }
    Klawisze()
    {
        for( u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i )
             KeyIsDown[ i ] = false;
       
    }
private:
    // Używamy by zgromadzić aktualny stan każdego klawisza (klucza)
    bool KeyIsDown[ KEY_KEY_CODES_COUNT ];
};

int main()

{
    // Tworzymy urządzenie
    Klawisze aktywne;
   
    IrrlichtDevice * device = createDevice( EDT_OPENGL, core::dimension2d < s32 >( 640, 480 ),
    32, false, false, false, & aktywne );
   
    video::IVideoDriver * video = device->getVideoDriver();
    scene::ISceneManager * menage = device->getSceneManager();
    scene::ICameraSceneNode * kam = menage->addCameraSceneNodeFPS( 0, 100.0f, 20.0f, 0, 0, 0, true );
    scene::ITriangleSelector * selector = 0;
    device->getCursorControl()->setVisible( false );
    kam->setPosition( core::vector3df( 0, 30, - 10 ) );
   
    // Tworzymy SkyBox (Niebo)
    video->setTextureCreationFlag( video::ETCF_CREATE_MIP_MAPS, false );
    menage->addSkyBoxSceneNode
    (
    video->getTexture( "media/img/sky/sy3.jpg" ),
    video->getTexture( "media/img/sky/sy6.jpg" ),
    video->getTexture( "media/img/sky/sy5.jpg" ),
    video->getTexture( "media/img/sky/sy2.jpg" ),
    video->getTexture( "media/img/sky/sy1.jpg" ),
    video->getTexture( "media/img/sky/sy4.jpg" ) );
    video->setTextureCreationFlag( video::ETCF_CREATE_MIP_MAPS, true );
   
    // Wczytywanie sceny
    menage->loadScene( "media/scena/mojirr.irr" );
   
    //Wczytywanie modelu
    IAnimatedMesh * pudlo = menage->getMesh( "media/mesh/pudlo.md2" );
    IAnimatedMeshSceneNode * pud = menage->addAnimatedMeshSceneNode( pudlo );
   
    pud->setScale( core::vector3df( - 10, - 10, - 10 ) );
    pud->setPosition( core::vector3df( 20, 10, 60 ) );
    pud->setMaterialFlag( video::EMF_LIGHTING, true );
    pud->setMaterialTexture( 0, video->getTexture( "media/img/pudlo.png" ) );
    pud->setMaterialTexture( 1, video->getTexture( "media/img/pudlo_2.png" ) );
    pud->setMaterialType( video::EMT_DETAIL_MAP );
   
    while( device->run() )
    {
        //Poruszanie do przodu, tyłu, lewo i prawo
        if( aktywne.IsKeyDown( irr::KEY_KEY_W ) )
        {
            core::vector3df v = pud->getPosition();
            v.Z += 0.1f;
            pud->setPosition( v );
        }
        else if( aktywne.IsKeyDown( irr::KEY_KEY_S ) )
        {
            core::vector3df v = pud->getPosition();
            v.Z -= 0.1f;
            pud->setPosition( v );
        }
        if( aktywne.IsKeyDown( irr::KEY_KEY_A ) )
        {
            core::vector3df v = pud->getPosition();
            v.X += 0.1f;
            pud->setPosition( v );
        }
        else if( aktywne.IsKeyDown( irr::KEY_KEY_D ) )
        {
            core::vector3df v = pud->getPosition();
            v.X -= 0.1f;
            pud->setPosition( v );
        }
        //Powiększanie obiektu
        else if( aktywne.IsKeyDown( irr::KEY_F2 ) )
        {
            core::vector3df v = pud->getScale();
            v.X -= 0.01f;
            v.Y -= 0.01f;
            v.Z -= 0.01f;
            pud->setScale( v );
        }
        //Obracanie obiektu
        else if( aktywne.IsKeyDown( irr::KEY_F1 ) )
        {
            core::vector3df v = pud->getRotation();
            v.Y += 0.04f;
            pud->setRotation( v );
        }
        else if( aktywne.IsKeyDown( irr::KEY_ESCAPE ) )
        {
            device->drop();
            return 0;
        }
        video->beginScene( true, true, video::SColor( 255, 0, 10, 200 ) );
        menage->drawAll();
        video->endScene();
    }
}


No i mamy wreszcie załadowaną kompletną scenę, a to tylko za pomocą jednej komendy:

C/C++
// Wczytywanie sceny
menage->loadScene( "media/scena/mojirr.irr" );

Ładujemy do naszego managera scenę, w tym wypadku scena była stworzona w irrEdit. W edytorze dodajemy modele typu: statyczne, animowane, particles, SkyBox'y. Oraz mamy spore możliwości, nad ich edycją.

Strona projektu znajduje się tu: IrrEdit

Za pomocą edytora można tworzyć kompletne sceny i załadować je za pomocą tej krótkiej linii kodu. Czyż to nie wspaniałe i proste.

Oczywiście za pomocą IrrEdit tworzymy tylko sceny, modele niestety musimy wykonać w innym sofcie, ja polecam "Blendera", można go porać z tej strony: blender.org

C/C++
scene::ICameraSceneNode * kam = menage->addCameraSceneNodeFPS( 0, 100.0f, 20.0f, 0, 0, 0, true );

W naszym kodzie dodaliśmy jeszcze do kamery opcje, która odpowiada za prędkość (tył/przód) jak i też odpowiedzialna jest za prędkość obracania się kamery. To jednak nie wszystko, parametr "true", który odpowiedzialny jest za obrót w wektorze v.X, jeżeli "true" zmienimy na "false" będziemy mogli przemieszczać się również kamerą w dół lub górę.

C/C++
// Tworzymy SkyBox (Niebo)
video->setTextureCreationFlag( video::ETCF_CREATE_MIP_MAPS, false );
menage->addSkyBoxSceneNode
(
video->getTexture( "media/img/sky/sy3.jpg" ),
video->getTexture( "media/img/sky/sy6.jpg" ),
video->getTexture( "media/img/sky/sy5.jpg" ),
video->getTexture( "media/img/sky/sy2.jpg" ),
video->getTexture( "media/img/sky/sy1.jpg" ),
video->getTexture( "media/img/sky/sy4.jpg" ) );
video->setTextureCreationFlag( video::ETCF_CREATE_MIP_MAPS, true );

Tu stworzyliśmy SkyBoxa, teraz do naszej sceny dodaliśmy własne chmury. Oczywiście textura nieba może być różna.

By poeksperymentować można z mojej stronki z działu download, pobrać różne typy SkyBox'ów: SkyBox
Oczywiście by zobaczyć nasze niebo, musimy wyjść z naszego pomieszczenia na zewnątrz

C/C++
pud->setMaterialFlag( video::EMF_LIGHTING, true );

W opcjach materiału naszego pudełka włączyliśmy reagowanie na światło, gdyż  w naszej scenie mamy już dynamiczne oświetlenie. Zostało wyeksportowane razem z całą sceną, oczywiście możemy tworzyć oświetlenie za pomocą kodu, ale o tym w innej lekcji.

C/C++
pud->setMaterialTexture( 0, video->getTexture( "media/img/pudlo.png" ) );
pud->setMaterialTexture( 1, video->getTexture( "media/img/pudlo_2.png" ) );
pud->setMaterialType( video::EMT_DETAIL_MAP );

No i jeszcze mała kosmetyczna zmiana, otóż na nasze pudełko nałożyliśmy jeszcze jedną texture. By nasz dodatkowy materiał był wyświetlany musimy podać jak nasze textury będą wyświetlane w tym wypadku EMT_DETAIL_MAP.

Materiały do pobrania

Pliki potrzebne do uruchomienia tej lekcji można pobrać z naszego repozytorium.
Poprzedni dokument Następny dokument
Klawiszologia Duplikowanie modeli na scenie