7 listopada 2009 Tutorial 1: HelloWorld


Ten tutorial pokazuje jak utworzyć IDE do używania silnika Irrlicht i jak napisać prosty program Helloworld. Program pokaże jak używać podstaw VideoDriver, GUIEnvironment i SceneManager. Microsoft Visual Studio jest użyty jako IDE ale będziesz też mógł zrozumieć wszystko jeśli używasz innego programu albo nawet innego systemu operacyjnego niż windows.

Plik nagłkówy <irrlicht.h> jest niezbędny do użycia silnika. Plik ten jest dostępny w the Irrlicht Engine SDK ścieżka 'include'. Żeby kompilator mógł znaleźć ten plik nagłówkowy, ścieżka musi być ściśle okreslona, sprecyzowana. To jest zależne od IDE i kompilatora jakiego używasz.

Wytłumaczenie jak to zrobić w Microsoft Visual Studio:
  • Jeśli używasz wersji 6.0, wybiesz Menu Extras -> Options. Wybierz directories tab i "include" item w combo box. Dodaj katalog 'include' w folderze silnika irrlich do listy innych katalogów. Teraz kompilator znajdzie plik nagłówkowy irrlicht.h. Musimy znaleść także irrlicht.lib, więc zostań w tym oknie, wybierz 'Libraries' w combo box i dodaj 'lib/VisualStudio'.




  • Jeśli twój IDE to Visual Studio.NET, wtedy wybierz Tools -> Options. Wybierz wejście projektów a następnie VC++. Wybierz 'show directories for include files' w combo box, i potem dodaj katalog 'include' w folderze silnika irrlich do listy innych katalogów. Teraz kompilator znajdzie plik nagłówkowy irrlicht.h. Musimy znaleść także irrlicht.lib, więc zostań w tym oknie, wybierz 'show directories for Library files' i dodaj 'lib/VisualStudio'.


I to by było na tyle. Z twoim tak ustawionym jak teraz IDE możesz rozwijać aplikacje z silnikiem Irrlicht.

Zacznijmy!

Po tym jak ustawiliśmy IDE, kompilator będzie wiedział gdzie znaleść pliki nagłówkowe silnika Irrlicht więc możemy je dołączyć do naszego kodu.

#include <irrlicht.h>

W silniku Irrlicht wszystko może być znalezione w przestrzeni nazw 'irr'. Więc jeśli chcesz użyć klasy silnika musisz napisać 'irr::' przed nazwą klasy. Na przykłas żeby użyć IrrlichtDevice piszemy: 'irr::IrrlichtDevice'. Żeby pozbyć się 'irr::' na początku nazwy każdej klasy, mówimy kompilatorowi że odtąd używamy tej przestrzeni nazw i nie bedziemy wtedy już musieli używać 'irr::'.

using namespace irr;

Istnieje 5 pod przestrzeni w silniku Irrlicht. Spójrz na nie, możesz przeczytać ich szczegółowy opis w dokumentacji. Tak samo jak z przestrzenią nazw 'irr' , chcemy używać 5 pod przestrzeni. Dlatego też mówimy znów kompilatorowi, ze nie chcemy ciągle pisać ich nazw.
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

By używać pliku Irrlicht.DLL, musimy połaczyć z Irrlicht.lib. Możemy ustawić tą opcję w ustawieniach projektu, ale żeby to ułatwić, używamy pragma comment lib dla VisualStudio. Na platformach Windows, musimy pozbyć się konsoli, która wyskakuje (pop up) podczas włączania programu z main(). To jest robione przez drugą pragme. Możemy także użyć metode WinMain, przez co jednak stracimy niezależność platformy.
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif

To jest główna metoda. Teraz możemy użyć main() na każdej
int main()
{ 

Najważniejszą funkcją silnika jest funkcja 'createDevice()'. Przez nią jest tworzony IrrlichtDevice który jest obiektem głównym do robienia czegokolwie z silnikiem. createDevice ma 7 parametrów:
  • dexiceType: Typ urządzenia. To może być na razie Null-device, jeden z software renderów, D3D8, D3D9, lub OpenGL. W tym przykładzie używamy EDT_SOFTWARE, ale żeby go wypróbować możesz chciec zmienić go na EDT_BURNINGSVIDEO, EDT_NULL, EDT_DIRECT3D8, EDT_DIRECT3D9, albo EDT_OPENGL.
  • windowSize: Rozmiar okna lub ekranu w FullScreenMode. W tym przykładzie używamy 640x480.
  • bits: Ilość kolorowych bitów na pixel. Powinno być 16 lub 32. Ten parametr jest zwykle pomijany gdy jesteśmy w windowed mode.
  • fullscreen: Określa czy chcemy żeby urządzenie działało w opcji fullscreen czy nie.
  • stencilbuffer: Określa czy chemy używać stencil buffera (do rysowania cieni).
  • vsync: Określa czy chcemy mięc dostępne vsync, to jest korzystne tylko w opcji fullscreen.
  • eventReceiver: Obiekt do odbierania zdarzeń. Jeśli nie chcemy uzywać tutaj tego parametru to wstawiamy 0.
Zawsze sprawdź wartość zwrotną żeby poradzic sobie z nieobsługiwanymi sterownikami, itd.
        IrrlichtDevice *device =
                createDevice( video::EDT_SOFTWARE, dimension2d(640, 480), 16,
                        false, false, false, 0);

        if (!device)
                return 1;

Napisz jakis ładny nagłówek, podpis. Pamiętaj o 'L' na początku.
device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");

Weź wskaźnik do VideoDriver, SceneManager i graficznego użytkownika środowiska interface, tak, żebyś nie musiał ciągle pisać device->getVideoDriver(), device->getSceneManager(), lub device->getGUIEnvironment().
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();

Dodajemy etykietkę hello world do okna używając środowiska GUI. Tekstjest w pozycji (10,10) w lewym górnym rogu i (260,22) jako dolny prawy róg.
        guienv->addStaticText(L"Hello World! This is the Irrlicht Software renderer!",
                rect(10,10,260,22), true);

Żeby pokazać coś interesującego, ładujemy model Quake 2 i pokazujemy. Musimy tylko mieć the Mesh z the Scene Manager z getMesh() i dodajemy SceneNode żeby pokazać Mesh z addAnimatedMeshSceneNode(). Sprawdzamy wartość zwrotna getMesh() żeby ujawnić problemy w ładowaniu i inne błędy.

Zamiast pisać nazwę pliku sydney.md2 jest możliwe załadowanie Maya object file (.obj), kompletny Quake3 map (.bsp) lub inny odpowiedni format pliku. A swoją droga, ten świetny model Quake 2 nazwany sydney został utworzony przez Briana Collinsa
        IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
        if (!mesh)
        {
                device->drop();
                return 1;
        }
        IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );


Żeby mesh wyglądał troche ładniej, zmienimy troszkę materiał. Wyłaczymy oświetlenie ponieważ nie chcemy dynamicznego światła tutaj i mesh byłby inaczej całkiem czarny. Pózniej ustawiamy pętlę ramek, żeby została wczesniej zdefiniowana nieruchoma animacja. W końcu, ustawiamy teksturę. Bez niej mesh narysowany byłby tylko przez kolor.
        if (node)
        {
                node->setMaterialFlag(EMF_LIGHTING, false);
                node->setMD2Animation(scene::EMAT_STAND);
                node->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp") );
        }

Żeby zobaczyć mesh ustawiamy kamerę w 3d w pozycji (0, 30, -40). Kamera skierowana jest do (0,5,0), co jest w przybliżeniu pozycją naszego modelu md2.
 smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

Ok, teraz gdy ustawiliśmy scenę, narysujmy wszystko: Włącz urządzenie w pętli while(), dopóki urządzenie nie będzie chciało dalej działać. To będzie wtedy gdy urzytkownik zamknie okno lub naciśnie ALT+F4 (lub jakimkolwiek innym kodem z klawiatury który będzie zamykał okno).
       while(device->run())
        {

Wszystko może być narysowane pomiędzy beginScene() a end Scene() call. The beginScene() call oczyszcza ekran z koloru i głębokiego bufferu, jeśli tego zarządamy. Wtedy pozwalamy Scene Manager i GUI Environment narysować ich zawartość. Z endScene() call wszystko jest zaprezentowane na ekranie.
            driver->beginScene(true, true, SColor(255,100,101,140));

                smgr->drawAll();
                guienv->drawAll();

                driver->endScene();
        }

Gdy skończymy z pętlą render, musimy usunąć Irrlicht Device utworzone wczesniej za pomocą createDevice(). W silniku Irrlicht musisz usunąć wszystkie obiekty które utworzyłes za pomoca metody lub funkcji która zaczynała sie od 'create'. Obiekt jest usunięty przez calling->drop().
               device->drop();

        return 0;
}

I to by było na tyle. Skompiluj i uruchom.
PiotrSOG