[ < ] |
[ > ] |
|
[ << ] |
[ Up ] |
[ >> ] |
|
|
|
|
[Top] |
[Contents] |
[Index] |
[ ? ] |
Most már van egy rendkívűl érdekfeszítő alkalmazásunk ami megnyit egy fekete ablakot és az ESC bilentyűre vár a kilépéshez. Feltételezhetjük, hogy ez az az alkalmazás, maire mindig is vágytál? Nem? Oké, akkor készítsünk némi 3D dolgot!
Adjunk hozzá egy textúra kezelőt, egy szobát (technikailag szektornak nevezzük), és némi fényt. Elsőként adj egy pointert a fő szektorunkra és egy CreateRoom() függvényt a 'Simple' osztály fejállományában:
|
... struct iSector; ... class Simple { private: ... iSector* room; float rotX, rotY; ... void CreateRoom (); ... |
Most add hozzá ezt a kódrészletet (textúra kezelő, szoba, fények) a 'simple.cpp'-hez:
|
bool Simple::Application () { ... // First disable the lighting cache. Our app is simple enough // not to need this. engine->SetLightingCacheMode (0); ... // These are used store the current orientation of the camera. rotY = rotX = 0; ... CreateRoom () ... } ... void Simple::CreateRoom () { // Load the texture from the standard library. This is located in // CS/data/standard.zip and mounted as /lib/std using the Virtual // File System (VFS) plugin. if (!loader->LoadTexture ("stone", "/lib/std/stone4.gif")) ReportError("Error loading 'stone4' texture!"); iMaterialWrapper* tm = engine->GetMaterialList ()->FindByName ("stone"); room = engine->CreateSector ("room"); csRef<iMeshWrapper> walls ( engine->CreateSectorWallsMesh (room, "walls")); csRef<iThingState> thing_state ( SCF_QUERY_INTERFACE (walls->GetMeshObject (), iThingState)); iThingFactoryState* walls_state = thing_state->GetFactory (); walls_state->AddInsideBox ( csVector3 (-5, 0, -5), csVector3 (5, 20, 5)); walls_state->SetPolygonMaterial (CS_POLYRANGE_LAST, tm); walls_state->SetPolygonTextureMapping (CS_POLYRANGE_LAST, 3); csRef<iLight> light; iLightList* ll = room->GetLights (); light = engine->CreateLight (0, csVector3 (-3, 5, 0), 10, csColor (1, 0, 0)); ll->Add (light); light = engine->CreateLight (0, csVector3 (3, 5, 0), 10, csColor (0, 0, 1)); ll->Add (light); light = engine->CreateLight (0, csVector3 (0, 5, -3), 10, csColor (0, 1, 0)); ll->Add (light); engine->Prepare (); } |
A további kód elsőként betölt egy textúrát a LoadTexture() függvénnyel. Az első paraméter a textúta engine által ismert neve, a második a VFS rendszerbeli fájlneve. Virtual File System (VFS)). Megjegyezzük, hogy ha nincs meg neked a 'stone4.gif' textúra, mást is használhatsz helyette. Az egyetlen feltétel, hogy a méretének a kettő hatványaival kell megegyeznie (pl. 64*64). A Crysal Space automatikusan átméretezi, ha nem felel meg ennek a feltételnek, de ez rontja a minőséget. A fügvény egy 'iTextureWrapper' tipussal tér vissza, amit most nem használunk. Ehelyett az 'iMaterialTexture' -t fogjuk használni, mai automatikusan létrejön a LoadTexture() meghívásával.
Ezután a CreateSector() meghívásával létrehzzunik a szobánkat. Ez a szoba kezdetben üres lesz. A szobát a Crystal Space-ben az 'iSector' reprezentálja, ami alapjában véve egy olyan tároló, ami geometriai objektumokat képes eltárolni. Az objektumok a Crystal Space-ben mesh objektumokként vannak jelen, (lásd a Mesh Object Plug-In System című részt) . Különféle mesh tipusok létenek a Crystal Space-ben. Minden más objektum tipus más módon jelenítimeg a geometriát. Ebben a tutoriálban csak a 'thing' (dolog) mesh objektum tipust fojuk használni. Ez a mesh objektum tipus nagyon jól hazánlható épületek belső falainak megjelenítésére.
Most meg fogjuk alkotni a sozbánk hat falát.
Elsőként létrehozzuk a thing mesh objektumunkat. Mivel
ez egy nagyon szokványos eset, létezik egy ezt
elkészítő tagfüggvény az engine-en (
CreateSectorWallsMesh() ) ami
létrehoz egy thingmesh objektumot és egy adott
szektorba teszi. Az egyetlen dolog, amit ezután meg kell tenni
az, hogy poligonokat adjunkhozzá a meshez. Ennek
véghezvitelére először lekérjük az
'iThingState' interfészt a
thing mesh objektumról. Az
SCF_QUERY_INTERFACE()
makrót
használjuk, ami az SCF része (lásd Shared
Class Facility (SCF)). Ez
látni fogja, hogy a mesh objektum (amit a mesh burkoló
burkol be), jelen pillanatban az 'iThingState'
-et implementálja (erről az esetről van most szó), és
visszatér egy 'iThingState”
tipusú pointerrel. Minden mesh objektum megvalósít
vaamilyen állapotinterfészt, amit amesh objektum
felálítására használunk.
Megjegyezzük, hogy minden mesh obektum, amit lekérsz az
SCF_QUERY_INTERFACE()
makró használatával,
elérhető lesz egészen addig, amíg szükséged
van rá ( a DecRef() )
Továbbá ebben a példában egy csRef<>
-hez rendeljük, ami elintézi helyettünk a DecRef()
meghívását. Hat rendezett poligon fog nekünk
létrehozni, amik belülről láthatóak.
(megjegyzzük, hogy a Crystal Space-ben akkor látható,
ha a vertexek az óramutató járásával
megegyezően orientálódnak).A visszatérés
során kapott thing állapotból most már
letudjuk kérni a gyár állapotát
('iThingFactoryState'), amit
poligonok létrehozására használhatunk.
Számos függvény létezik egyéni
poligonok létrehozására, ha akarod, de ebben az
esetbngy egyszerű függvényt használunk egy doboz
létrehozására, ami csak belülről látható.
Ez fogja nekünk a falakat szolgáltatni. Ezt az
AddInsideBox() fogja megtenni. Az
objektum térben adjuk meg az AddInsideBox()
függvénynek a doboz koordinátáit ( nem a
kamera térrel vagy a világ térrel).
A SetPolygonMaterial() függvény fogja beállítani a poligonok anyagát. Az első paraméter a távolság. A CS_POLYGON_LAST makrót használjuk annak a jelzésére, hogy minket az utolsóként létrehozott poligon anyaga érdekel (azok a polignok amiket az AddInsideBox() hozott létre).
A textúrát a
SetPolygonTextureMapping()
használatával
húzzuk fel. Ebbe a tutoriálban a lehető leegyszerűbb,
de működő megoldást fogjuk választani. Ebben az
egyedi esetben tehát vesszük minden, a dobozt alkotó
poligon első két vertexét és ezt használjuk
a textúra u tengelyének. A v tengely az u tengely
merőlegeseként lesz kiszámolva. A harmadik paraméter
azt jelzi, hogy a textúrát úgy méretezzük,
hogy egy textúra csempe 3*3 világ koordináta
egység méretű lesz.
Végül létrehozuk némi fényt a
szobánkban, hogy hogy láthassuk a falakat. Az
'iLight' interfész reprezentálja a fényt.
Eben az esetben statikus fényeket haszánlunk, mivel
neakrjuk semmozgatni, sem az intenzitását változtatni.
Három ilyen fényt alkotunk és a szobához
adjuk az AddLight() segítségével.
Megjegyezzük, hogy a fények listáját az
'iLightList' interfészt
egvalósító osztály tárolja egy
adott szektoron blül. A listát a iSector::GetLights()
meghívásával érhetjük el.
A fények létrehozásánál használunk néhány paramétert. Elsőször is nevet adunk aénynek. Ez nem túl gyakran használats ezért 0-ra állítjuk. A másdik paraméter a fény hele a világban. Ezuátn a sugár következik. A fény nem hat az olyan poligonokra, amik kívűl esek a középponttal és a sugárral meghatározott gömbön. A következőparaméter fény színe RGB formában, ahol az <1,1,1> jelenti az abszolút fehéret és a <0,0,0 > az abzzolút feketét. Az utolsó paraméterrel adjuk meg, hogy akarjuk-e, hogy a fényünk pszeudo-dinamikus lgyen-e. A pszeudodinaimkus fény nem mozoghat, de képes változtatni az intenzitását. Van némi teljesítménybeli ára a használatának, ezért nem alapértelemezett.
A Prepare() meghívásával előkészítjük az engine-t a jelenet renderelésére. Előkészít minden textúrát és létrehoz minden fénytérképet (lightmap) ami szükséges. Csak ezután tudod megkezdeni a világ renderelését, mivel a fénytérképek átkonvetálódnak a válaszott 3D renderernek megfelelőbb formára.
Oké, létrehoztuk a szobánkat és helyesen előkészítettük azt. Ha lefordítod és futtatod az alkalmazást, egy fekete képernyőt fogsz látni. Miért? Mert nem készítetünk kamerát, amivel ránézhetnénk a szobára.
[ < ] |
[ > ] |
|
[ << ] |
[ Up ] |
[ >> ] |
This document was generated using texi2html 1.76.