Az előző alkalommal megismerkedhettek a VRML nyelv négy alapobjektumával. Ebben a cikkben az objektumok bemutatását folytatjuk, majd egy kis kitérőt teszünk a koordináta-geometria területén.

Nézzük, hogy még milyen objektumokat készíthetünk nagyon egyszerűen a VRML nyelv segítségével.

AsciiText

Ez az elem egy szöveget ír ki a képernyőre. Ahogy a neve is mutatja, a szövegben ASCII karaktereket használhatunk. A szöveg a koordináta rendszer 0,0,0 pontjában fog kezdődni, míg a továbbiak elhelyezkedését az elsőben megadott paraméterek fogják meghatározni. A szöveg tartalmi része mellett megadhatjuk a méretét, a betűk közötti távolságot, az igazítást és a szélességet.

A szöveg képének elkészítése balról jobbra és föntről lefelé történik olyan betűtípussal, amelyet a FontStyle változóban adunk meg. A kirajzolásnál a kép elkészítésénél az aktuális anyagot és színeket alkalmazzuk. Amennyiben ezek nem megfelelő értékek, akkor a szöveg definiálása előtt meg kell változtatni ezeket.

Az AsciiText általános alakja a következő:

#VRML V1.0 ascii AsciiText{    string        "megjelenítendő szöveg"  # Megjelenítendő szöveg   spacing       valós szám               #   justification LEFT, RIGHT, CENTER      # A szöveg igazítása   width         valós szám               # A szöveg szélessége }

A szélesség mező meghatározza a renderelés maximális szélességét minden szövegre. Ha a szöveg túl hosszú, akkor az automatikus méretezést kell választani. Ezt úgy tudjuk elérni, hogy a width tulajdonságnak 0 értéket határozunk meg. A másik lehetőségünk, hogy kihagyjuk a tulajdonságok felsorolásánál a width paramétert. Ilyen esetekben is az optimális szélességet fogja a program figyelembe venni.

A szöveg elhelyezkedését a justification tulajdonság fogja meghatározni. Három értéket vehet fel:

  • LEFT értéket használva a szöveg balra igazított lesz, ami azt jelenti, hogy a 0,0,0 koordinátába az első betű bal alsó sarka kerül.

  • RIGHT szóval a szöveget jobbra igazíthatjuk, tehát az utolsó betű jobb alsó sarka kerül a koordináta rendszer origójába.

  • CENTER értékkel a szöveg közepe fog az origóba kerülni.

A különböző igazítások hatását vehetjük szemügyre az alábbi kis VRML fájlban. Vizsgáljuk meg, hogy mi is szerepel a kódban:

#VRML V1.0 ascii FontStyle { size 1 family TYPEWRITER style BOLD } Translation { translation 0 2 0} AsciiText{ string "LEFT" spacing 1 justification LEFT width 0 } Sphere{ radius 0.1} Translation { translation 0 -2 0} AsciiText{ string "CENTER" spacing 1 justification CENTER width 0 } Sphere{ radius 0.1} Translation { translation 0 -2 0} AsciiText{ string "RIGHT" spacing 1 justification RIGHT width 0 } Sphere{ radius 0.1}

A kód nem bonyolult, bár vannak benne olyan részek, amelyeket eddig még nem tárgyaltunk. Ettől függetlenül minden bizonnyal sikerül megérteni a működést. Nézzük akkor blokkonként, hogy miről is van szó.

FontStyle { size 1              # A szöveg méretének beállítása family TYPEWRITER   # A betűtípus megadása style BOLD          #A félkövér stílus definiálása }

Ebben a részben a betűtípust, állítjuk be, valamint a szöveg méretét és a félkövér stílust.

Translation { translation 0 2 0}   # Eltolás Y irányban

Ez a rész még szintén ismeretlen. A szöveg eltolásáért felelős. Pontosabban nem is a szöveget toljuk el, hanem a koordináta rendszer kezdőpontját, mégpedig Y irányban +2 értékkel. Ez lesz az első sor pozíciója. Miután egyszer eltoltuk a kezdőpontot, az számít az alappontnak. Éppen ezért a második szövegnél az eltolást Y irányban -2-re kell választani, így visszatérünk az eredeti origóba. A harmadik sornál még egyszer -2-vel csökkentjük a függőleges eltolást. Az eltolással és a különböző térgeometriai műveletekkel a következő részben fogunk foglalkozni.

Sphere{ radius 0.1}  # 0.1 sugarú gömb

Annak érdekében, hogy könnyebben láthassuk az igazítás kezdőpontját, az aktuális koordináta rendszer kezdőpontjában elhelyezünk egy-egy gömböt. Gömböt már tudunk rajzolni, tudjuk, hogy azt a Sphere objektum fogja meghatározni. A sugarát a gömbnek 0.1-re választjuk meg.

Ezek után következhet a szöveg kiírása, amely a már megismert módon történik. Az egyes blokkokban a szöveg értékét az igazítás elnevezésére állítjuk be, így rögtön látjuk, hogy melyik igazításnak mi a hatása.

AsciiText{ string "LEFT"        # A szöveg értéke spacing 1 justification LEFT   # Az igazítás módja width 0}             # Szövegszélesség automatikus

Mivel már volt róla szó és a továbbiakhoz is elengedhetetlen, nézzük meg a FontStyle tulajdonságot, illetve a különböző beállítási lehetőségeket.

FontStyle

A FontStyle tulajdonság az AsciiText objektum szövegének alapvető beállításait tartalmazza. A FontStyle általános alakja a következő:

FontStyle{ size    # A betűk mérete family  # A betűtípus meghatározása style   # A betűstílus beállítása }

A size paraméter a betűk magassági méretét határozza meg. A family tulajdonság alatt kell beállítanunk, hogy milyen legyen az alkalmazni kívánt betűtípus. Nem használhatunk itt bármit, hanem három csoportból kell választanunk:

  • SERIF - Ezzel a tulajdonsággal Serif típusú betűtípust választhatunk. Többek között ide tartozik a Times New Roman betűtípus is, amelyet nagyon sok helyen használnak.

  • SANS - Ez a Sans Serif típusokat foglalja magába. Ilyen a Helvetica betűtípus is.

  • TYPEWRITER - Ebbe a csoportba azok tartoznak, amelyek írógépek karaktereihez hasonlóan néznek ki. Ide tartozik a Courier betűtípus is.

Miután kiválasztottuk a betűméretet és a típust, akkor meg kell adnunk a betűk stílusát is. Itt sem választhatunk bármit, a nyelv specifikációja megszabja a lehetséges értékeket:

  • NONE Nincs semmilyen különleges betűstílus.
  • BOLD Ezzel a betűket vastagítani lehet, ez felel meg szövegszerkesztőkben használt félkövér stílusnak.
  • ITALIC A szövegszerkesztőkben szintén használt dőlt betűstílust tudjuk ezzel bekapcsolni.
Az alapértékek a következők:
FontStyle {           size     10      # betűméret 10, ami igen nagy, ezért általában csökkentjük           family   SERIF    # A betűtípus a Sans Serif családba tartozik           style    NONE    # Nincs beállítva betűstílus }
Összefoglalásul készítsünk el egy egyszerű alakzatokból álló, de az eddigieknél bonyolultabb testet. A kód egyszerű és jól felismerhető, ezért elkészítése, vagy akár módosítása nem okozhat problémát. Az ábrán ezt a képet kell látnunk:

A kód ide kattintva érhető el.

#VRML V1.0 ascii Cube{                   # Készítünk egy kockát, amelynek méretei:           width 1       # Szélessége 1           height 1      # Magassága 1           depth 1}      # Mélysége 1 Sphere{                 # Ebbe beleteszünk egy gömböt           radius 0.7}   # melynek sugara 0.7 Cylinder{               # Készítünk egy lapos nagy átmérőjű hengert           radius 1.25   # amelynek az sugara 1.25           height 0.05}  # a magassága pedig 0.05 Cylinder{               # Ismét hengert definiálunk,           radius 0.4    # amelynek sugara 0.4           height 2}     # a magassága pedig 2 Cylinder{               # A harmadik hengerünk ebbe kerül bele, ugyanis           radius 0.3    # sugara 0.3,           height 3}     # a magassága pedig 3 Cylinder{               # A negyedik henger lesz a tengely,           radius 0.1    # mivel a sugara 0.1 és           height 6.0}  # a magassága 6

Ezzel a geometriai alakzatok tárgyalását befejeztük, de az eddig megismert objektumokat nem szabad elfelejteni, hiszen ezekből készülnek majd a bonyolultabb alkotásaink is.

Színek, anyagok használata a VRML térben

Az eddig elkészített alakzataink mindegyike azonos, szürke színű volt. Sok esetben egy különböző színeket tartalmazó objektum sokkal több információ hordozására alkalmas, mint az egyszínűek. Az ember nagyon vizuális lény, a különböző színek használata az agyban nyomatékosításként is megjelenhet.

Ha mindez így van, akkor miért ne használnánk mi is ezeket a lehetőségeket?

A VRML 1.0 nyelvben a színek beállításához a Material változót kell használnunk. A beállított értékek abban a csoportban kerülnek érvényesítésre, amelyben elhelyeztük őket.

A színek megadásánál színkeverést használunk, amelynek során a vörös, a zöld és a kék színeket megfelelő arányban keverjük össze. Az ilyen elven működő színmegadást RGB (Red – vörös, Green – zöld, és Blue – kék) színkeverésnek is nevezik. Általában ezt a megjelenítési módot használják a különböző monitorok is. Minden színhez tartozik egy index, amely az adott szín súlyát jelenti a megjelenítéskor. Az indexek 0 és 1 közöttiek lehetnek. A 0 felel meg a 0%-nak, míg az 1 a 100%.

A színek megváltoztatásáért a Material tulajdonságblokkban elhelyezett tulajdonságokat kell megváltoztatnunk. Nézzük, hogy is néz ki a blokk az általánosságban:

#VRML V1.0 ascii Material{           ambientColor     R G B        # A környező szín megadása           diffuseColor     R G B        # A szétterjedő szín mértéke           specularColor    R G B        # A világos részek színe           emissiveColor    R G B        # A sugárzó szín meghatározása           shininess      Valós szám     # A fényesség mértéke           transparency   Valós szám     # Az objektum átlászóságának értéke }

Nézzük végig, hogy mire is szolgálnak az egyes tulajdonságok.

  • Az ambientColor tulajdonsággal a környező színt lehet megadni. Ez lesz a tárgyak alapértelmezett színe, amely a ráeső fénytől függően jelenik meg.

  • A diffuseColor a szétterjedő színt határozza meg. Ez határozza meg az egyes tárgyak felületén szétterjedő fényt, amely a tárgyat megvilágító fényforrásoktól függ.

  • A spectularColor határozza meg a világos, tükröződő részek színét. Ilyent láthatunk például egy megvilágított almán, amelyen egy valamekkora kiterjedésű pontban egy világos, tükröző folt jelenik meg. Ha a beeső fény közel van a felülethez és a nézőponttal kis szöget zár be, akkor a spectularColor változó értéke hozzáadódik az ambientColor és a diffuseColor változó értékéhez. A megjelenítésnél ennek a változónak a kiértékelésekor figyelembe veszik a shininess változóban tárolt értéket. Minél kisebb számot adunk itt meg, annál kisebb súllyal veszi a program figyelembe a specularColor változóban tárolt értéket.

  • Az emissiveColor az “izzó” objektumoknál játszik szerepet. Olyankor használjuk, amikor egy objektum sugárzásának mértékét kell beállítani.

  • A shininess paraméterről már az előzőekben volt szó, a spectularColor változó figyelembevételének a súlyát határozza meg.

  • A transparency változóban az áttetszőséget állíthatjuk be. Az értéke 0.0 és 1.0 közötti lehet. A 0.0 érték megadásával az objektum egyáltalán nem lesz átlátszó, míg az 1.0 jelenti a 100%-os átlátszóságot.

Az egyes értékeket megváltoztathatjuk, az az adott blokkban kerül érvényesítésre. Mindig csak azokat a paramétereknek kell új értéket adnunk, amelyek változnak az adott blokkban, az összes többi megtartja előző értékét. Ez az öröklődés, amely lerövidítheti az egyes elemek leírását.

A különböző változók rendelkeznek alapértelmezett értékkel. Emiatt lesz minden tárgy, amelynek a színét nem változtatjuk meg, szürke színű. Nézzük tehát az alapértékeket:

Material{           ambientColor 0.2 0.2 0.2   # A környező szín értéke           diffuseColor 0.8 0.8 0.8   # A szétterjedő szín tónusa szürke           specularColor 0 0 0        # A tükröződő részek színe           emissiveColor 0 0 0        # Az izzó objektumok színe           shininess 0.2              # A tükröződés figyelembevételének mértéke           transparency 0             # A tárgyak nem átlátszók }

A képernyő hátterének megváltoztatása

A képernyő hátterének megváltoztatása egy kicsit másként történik:

DEF BackgroundColor Info {           string "0.3 0 1 " # Kékeslila szín }

Definiálnunk kell egy BackGroundColor változót, amely a program számára egy szöveget ad át. Ennek a szövegnek az értéke fogja megadni a három szín keverésének arányát,a telítettségüket. A szöveget a string szó vezeti be, ami után „” közé kell tenni a kívánt karaktereket.

Ezek után már mi is elő tudunk állítani különböző színű objektumokat. Ha ide kattint, akkor a VRML böngészőben az előző, összetett testünket láthatja, amelyet kiszíneztünk, valamint kicseréltük a háttér színét is, emellett a kockánkat félig áttetszővé tettük. Nézzük meg a kódot is:

#VRML V1.0 ascii    DEF BackgroundColor Info {          # Kekeslila              string "0.3    0   1  "     } Separator{                             # A kocka tulajdonságai Material{                      # egyedül a kockára érvényes diffuseColor 0 0 0     # Színe fekete, transparency 0.5       # valamint félig átlátszó } Cube{                          # Itt definiáljuk a kockát width 1                # Szélessége 1 height 1               # Magassága 1 depth 1}               # Mélysége 1 } Separator{                             # Megváltoztathatjuk a gömb Material{                      # tulajdonságait diffuseColor 1 1 1     # Színe fehér. Az átlátszóság csak }                              # az előző blokkban volt érvényes Sphere{                        # Gömb definiálása radius 0.7}            # Sugara 0.7 } Separator{                             # Ez a blokk a tányérhoz tartozik Material{ diffuseColor 0 0 1     # A színe kék lesz } Cylinder{                      # A henger definíciója radius 1.25            # A sugara 1.25 height 0.05}           # A magassága pedig 0.05 } Separator{                             # A legnagyobb átmérőjű függőleges Material{                      # tengely megadása diffuseColor 0 1 0     # A színe zöld } Cylinder{ radius 0.4             # A sugara 0.4 height 2}              # A magassága 2 } Separator{                             # A következő tengely meghatározása Material{ diffuseColor 1 1 0     # A színe sárga } Cylinder{ radius 0.3             # A sugara 0.3 height 3}              # A magassága 3 } Separator{                             # A legvékonyabb tengely adatai Material{ diffuseColor 1 0 0     # Színe piros } Cylinder{ radius 0.1             # A sugara 0.1 height 6.0}            # Magassága 6

Kép ráfeszítése a felületre

Nem csak színeket alkalmazhatunk a felületek kirajzolásánál. A Texture2 node alkalmazásával egy megadott képet feszít a program a felületre. Ezeket a képeket textúráknak nevezzük és kis méretű, különböző méretű képekből készíthetjük el ezeket.

A Texture2 felépítése a következő:

Texture2 {       filename ""              # Itt kell megadni a fájlnevet       wrapS    REPEAT/CLAMP    # A kép felületre feszítésének módja       wrapT    REPEAT/CLAMP    # A kép felületre feszítésének módja }

A textúrának a megadásához a fájlnevet az elérési úttal együtt kell megadni. A megadás szintaktikája olyan, mint amilyent az URL címekhez használunk. Amennyiben nem határozzuk meg az útvonalat, úgy a böngésző az aktuális könyvtárban keresi a fájlt. Ha nem talál ilyen nevűt, egyszerűen kihagyja és az aktuális Material változókkal hozza létre a felületeket. A képek formátumánál ajánlott a PNG formátumot használni, de a programok elboldogulnak a JPEG képekkel is. A GIF állományokat is képes a program megjeleníteni, azonban a GIF formátum zártsága miatt ennek használatát lehetőségek szerint mellőzzük. Az ilyen textúrákat valamilyen program segítségével célszerű átkonvertálnunk az említett formátumok egyikére.

Bizonyára mindenki tudja, hogy a JPEG egy veszteséges tömörítési eljárás, amelynek során az olyan részeket, amelyek a képben nem okoznak torzulást, eltávolítják. A JPEG képek minősége a tömörítési arányuktól függ, annak növelésével a minőség jelentősen csökken. Az ilyen formátumú képek lényegesen kisebb méretűek, mint a tömörítetlen képek. A weben való megjelenés során a méret nagyon fontos, mivel a nagy képek lassabban letöltődő oldalakat jelentenek. Ha lassú az oldalunk, akkor valószínűleg azzal sok látogatót elriaszthatunk még akkor is, ha a tartalom versenyképes.

A PNG egy viszonylag új képtárolási eljárás. A legfőbb tulajdonsága, hogy támogatja az átlátszó rétegeket. Az ilyen módon elmentett képek háttere áttetsző lesz, ami elősegíti a kép lapba illeszkedését. Hátránya, hogy egyes, általában régebbi böngészők nem tudják helyesen megjeleníteni az ilyen formátumú képeket. Szerencsére már gyakorlatilag az összes fontos böngésző program új változata kifogástalanul képes kezelni a PNG képeket.

A textúrák lehetnek akár színesek (full RGB color), akár szürke (grey scale) árnyalatosak. Természetesen a PNG formátum esetén rendelkezhetnek átlátszó (transparency) paraméterrel is. Ezek a tulajdonságok nagyon nagy mértékben meghatározzák a megjelenítő program működését. Nem szabad figyelmen kívül hagyni, hogy itt is fontos szerepet játszik a textúra mérete. A megjelenítés előtt le kell tölteni az internetről, ami időt vesz igénybe. Ezt követően a megjelenítő programnak rá kel feszíteni az adott test vagy testcsoport felületére, ami szintén erőforrásokat igényel, vagyis időbe telik. Minél tovább tart egy VRML világ megjelenítése, annál kevesebben fogják azt megtekinteni. Szerencsére ez nagyon nem fenyeget minket, legalábbis az egyszerűbb világoknál, ugyanis a VRML állományok kicsit, így gyorsan letölthetők, a számítógépek teljesítménye pedig már nem szab határt a gyors megjelenítésnek.

Nagy kiterjedésű, bonyolult világoknál, amelyekben sok és nagy méretű textúrákat alkalmaztunk, valamint ezeket kombináltuk különböző színes felületekkel, a megvilágítástól függően a mozgás során bekövetkező számítási művelet nagyon sokáig is eltarthat. Ez akadozott mozgást eredményez, amelynek következményeként élvezhetetlen lesz a látvány. Amikor ilyen világokat készítünk, gondoljunk az optimalizálásra. Az egyik lehetőségünk, hogy kikapcsoljuk a megvilágításokat, amikor a textúrák engedélyezettek.

A textúrák felületre feszítésének módját adja a meg a wrapS és a wrapT változó. Ezek azt határozzák meg, hogy mi történjen akkor, ha a textúra koordinátája kívül esik a 0-1 tartományon. Külön dönthetjük el, hogy mi történjen függőleges (vertikális, wrapT) és vízszintes (horizontális, wrapS) irányban.

Két lehetőségünk van:

  • A REPEAT beállítást választva a textúrát a megjelenítő program ismételni fogja a teljes felületen keresztül. Például, ha a textúra méretezési faktora 16 (következő fejezetben lesz róla szó), akkor a megjelenítés során a program 16-szor fogja ismételni az adott textúrát.

  • A CLAMP értéket használva nem ismételi a program a textúrákat, hanem kinyújtja annyira, hogy kitöltse a teljes felületet.

Az előbbieket szemlélteti az alábbi kis VRML világ.

A következő részben elkezdünk megismerkedünk a tér felépítésével, a különböző térgeometriai fogalmakkal, valamint a térben való mozgással. Addig is a kedves olvasóra bízzuk, hogy készítsen el bonyolultabb elemeket, világokat, amelyeken keresztül gyakorolhatja az alapobjektumok létrehozását. Kiváló gyakorlási lehetőség a testek áthatásának vizsgálata, bár ehhez az igazán látványos elemeket csak a következő részben ismerjük meg.