Alapok Az OpenGL alapfogalmai

Az OpenGL  primitíveket rajzol. A primitívek grafikai alapelemek. Az OpenGL geometriai primitívei a pontok, a szakaszok és a sokszögek (poligonok).A geometriai primitíveket vertexek (csúcspontok, 3D pontok) definiálják. Egy vertex definiálhat egy pontot, egy szakasz végpontját, vagy egy polygon csúcspontját, tehát minden OpenGL geometriai primitívet meg tudunk határozni a vertexeivel. A vertexek struktúrák, melyek tartalmazzák az illetõ csúcspont térbeli koordinátáit, színét és egyéb adatait. Az OpenGL minden vertexet függetlenül, rendezetten és ugyanúgy kezel.
    Az OpenGL más struktúrákat is használ, például pixelnégyszögeket, bittérképeket. Ezeket raszterprimitíveknek nevezzük. Fontos, hogy megkülönböztessük a geometriai és raszterprimitíveket, mivel azokat az OpenGL eltérõ módon kezeli.
    Az OpenGL-t állapotautomataként is fel lehet fogni, mivel rendelkezik egy ún. state-tel (állapot). Ezen state tartalmazza azokat az érvényes adatokat, amelyek szükségesek a specifikált objektumok leképezéséhez. Tárolja, hogy pl. a világítás, azon belül mely fényforrások, az élsimítás, az árnyalás, stb. engedélyezve van, vagy le van tiltva. Ezeket az információkat általában egyetlen bit tárolja, ha a bit 1 akkor engedélyezett, ha 0 akkor nem.
    Az OpenGL-ben minden felhasznált paraméter rendelkezik egy iniciális vagy alapértelmezett (default) értékkel, pl: az alapértelmezett RGBA szín az  (1.0, 1.0, 1.0, 1.0); az alapértelmezett transzformáció és vetítési mátrix pedig az egységmátrix.

Koordináta-rendszerek

Az OpenGL a megjelenítéskor a Descartes féle koordináta rendszert használja (Cartesian coordinate system), tehát a bázis olyan vektorokból áll, melyek mindegyike merõleges a többire. A koordinátákat a megszokott x, y, z hármassal jelöljük. Mivel a számítógépes grafikában leggyakrabban a jobbsodrású rendszerek használatosak, ezért az OpenGL is ezt használja. Jobbsodrású koordináta-rendszer esetén a (0, 0, 0) pontban van az origó, az x, y tengely pozitív része az origótól jobbra ill. fölfelé található, a z tengely pozitív része a képernyõbõl kifelé mutat.
 

Szín módok

Az OpenGL kétféle szín módot használ: az RGBA szín módot, illetve a szín index módot. Az RGBA szín módban minden színt négy  komponens definiál, a vörös (Red), zöld (Green), kék (Blue), illetve az alpha (Alpha) komponens. Minél nagyobb a komponens értéke, annál intenzívebben vesz részt a létrejövõ színben. Szín index módban minden színt egy lebegõpontos érték ír le, és minden ilyen lebegõpontos értékhez hozzá van rendelve három 8 bites érték a memóriában, rendre a három szín intenzitása.

Szín mélység

    Mint ahogy a képernyõ felbontásának finomsága, a megjeleníthetõ színek száma is befolyásolja a kép részletességét, valósághûségét. A szín mélység azt jelenti, hogy a pixelek színét hány biten ábrázoljuk. 8-bites színmélység esetén 256 különbözõ szín megjelenítésére van lehetõségünk. 24-bites színmélység esetén egy pixel színét 24 bittel írjuk le, mégpedig úgy, hogy mindhárom színkomponenst intenzitását 8 biten ábrázoljuk.
    A teljesítmény növelése érdekében egyes videokártyák más szín módokkal is rendelkezhetnek, pl. a 32 bites, vagy true color szín móddal. A 32 bites szín módban ugyan nem tudunk több színt kikeverni, mint a 24 bites szín módban, de teljesítmény szempontjából a 32 bites szín mód van elõnyben, mivel itt gyorsabb a memóriahozzáférés, viszont van 8 elvesztegetett bit.
 

Homogén koordináták

Az OpenGL parancsok általában 2 és 3 dimenziós vertexekkel dolgoznak. Az OpenGL minden vertexet olyan 3 dimenziós vertexként tárol, melynek 4 koordinátája van. Minden (x, y, z, w) oszlop vektor egy homogén vertexet reprezentál, ha a vektorban legalább az egyik komponens nem nulla. Ha az a valós szám nem nulla, akkor  (x, y, z, w) és (a*x, a*y, a*z, a*w) ugyanazt a homogén vertexet reprezentálja. Egy (x, y, z) 3 dimenziós euklideszi pont az (x, y, z, 1.0) homogén vertexnek, egy (x, y) 2 dimenziós euklideszi pont pedig az (x, y, 0.0, 1.0) homogén vertexnek felel meg.
    Ha w nem nulla, akkor az (x, y, z, w) homogén vertex az (x/w, y/w, z/w) 3 dimenziós pontnak, ha w = 0.0 akkor pedig egy végtelen távoli ideális pontnak felel meg. A végtelen távoli pontok megértéséhez tekintsük az (1, 2, 0, 0) pontot, és az
(1, 2, 0, 1), (1, 2, 0, 0.01), (1, 2, 0, 0.0001) pontokat; ezek a pontok az (1, 2), (100, 200), (10000, 20000) euklideszi pontoknak felelnek meg. Ez a sorozat a 2x = y egyenes mentén távolodik a végtelenbe. Most már látjuk, hogy az (1, 2, 0, 0) pont ezen egyenes irányában, végtelen messzi van.
    Homogén koordináták használata több okból is indokolt lehet a számítógépes grafikában. Használatukkal lehetõvé válik, hogy a grafikában alkalmazott transzformációkat (eltolás (translate), forgatás (rotate), nagyítás (scale), nyírás (sheering)), és ezen transzformációk kompozícióját mátrixszorzásokkal el lehet végezni. Fontos szerepet kapnak a homogén koordináták a vágási feladat megoldásánál is.

Normálok

Egy felülethez tartozó normál vektor (vagy normális) egy, a felületre merõleges egységnyi hosszúságú vektor. Minden normális egy háromdimenziós vektor, tehát egy normálisnak x, y és z komponense van, és mivel minden normális egységnyi hosszúságú, ezért sqrt(x^2 + y^2 + z^2) = 1.  Egy sík felület esetén, a merõleges irány a felület összes pontjára ugyanaz, de egy nem egyenletes felület esetén, a normális a felület minden pontján más és más lehet. Az OpenGL-ben minden polygonhoz és minden vertexhez tartozik normális. Ugyanazon polygon vertexei ugyanazzal a normálissal is rendelkezhetnek, de lehetnek különbözõ normálisaik is. Egy polygon normálisát az OpenGL általában a vertexeinek a normálisaiból számítja ki. Normálisokat azonban csak vertexekhez specifikálhatunk.
    Egy objektum normál vektora a felszínének az irányát definiálja - általában a fényforrásokhoz relatívan. A normálisokat a számítógépes grafikában  több helyen is alkalmazzák. Ahhoz, hogy egy sík egyenletét le tudjuk írni, szükségünk van a sík normálisára, vagyis egy, a síkra merõleges vektor koordinátáira. Ekkor a sík egyenlete a következõképpen néz ki:

                               Ax + By + Cz + D = 0

Fontos szerepet kapnak a normálisok az árnyalási feladatnál, a látható felszínek, vonalak meghatározásakor, illetve a megvilágítási feladatnál is. (például polygon határú síklapokkal határolt test hátra nézõ lapjait a normálisok segítségével határozhatjuk meg.)

Koordináta transzformációk

Vertex transzformáció

    A vertexeket, normálisokat és textúra koordinátákat az OpenGL transzformálja, mielõtt azokat felhasználná egy kép megalkotásában. A vertex transzformációkat ( forgatás, eltolás, skálázás, nyírás )  4×4-es mátrixként reprezentálhatjuk. Ha v egy homogén vertexet reprezentál, M pedig egy 4×4-es transzformációmátrix, akkor M*v a v vertex képe az M transzformáció után.
    A vertex koordinátákat objektumkoordinátáknak nevezzük, tehát egy vertex objektum koordinátái azok a koordináták, amelyeket a glVertex parancsban megadunk.. Az objektum koordinátákat a modell-nézet vagy ModelView mátrix transzformálja ún. szem vagy eye koordinátákká. A szem koordinátákból a vetítési vagy Projection mátrix által lesznek az ún. clip koordináták. Ez a transzformáció egy ún. viewing volume (látótér)-t definiál (amely párhuzamos vetítés esetén egy téglalap, perspektivikus vetítés esetén pedig egy csonkagúla), úgy, hogy az ezen kívül esõ objektumokból vágott objektumok lesznek, így azok a végsõ képen nem fognak látszani. Ezután egy ún. homogén osztás (perspective division) következik, és a clip koordináták normalizált eszköz koordinátákká (normalized device coordinates) transzformálódnak. Ezután már csak egy nézeti (viewport) transzformáció szükséges, és létrejönnek az ablak koordináták.
    A gyakorlatban ez így néz ki (jelen esetben a vertexek oszlopvektorral való reprezentálását használjuk, így az adott vertexet mindig balról szorozzuk a transzformációmátrixszal (ez egyébként dr. Kuba Attila jegyzetében is így van, ezért biztosan ismerõs lesz); vannak források, melyek a másik megoldást használják, miszerint sorvektorokat szoroznak jobbról a transzformációmátrixszal, ekkor a transzformációmátrix is némiképp módosul, reméljük ez nem okoz semmi zavart (de hogy ne kelljen feleslegesen gondolkozni, elárulom hogy egyszerûen transzponálni kell a mátrixot;)):
        Legyenek egy vertex objektum koordinátái (x0, y0, z0, w0) (ez tehát egy oszlopvektor, azaz képzeljünk a vektor kitevõjébe egy T betût), és legyen a modell-nézet mátrix M. ; ekkor a vertex szem koordinátáit a következõképpen kapjuk:

                                            (xe, ye, ze, we ) = M*(x0, y0, z0, w0),

tehát egy vertex szem koordinátáit úgy kapjuk, hogy az objektumkoordináta vektorát beszorozzuk balról a modell-nézet mátrixszal. Ugyanígy, ha P a vetítési mátrix, akkor a vertex clip koordinátái:

                                            (xc, yc, zc, wc) = P*(xe, ye, ze, we),

tehát egy vertex vetítés koordinátáit úgy kapjuk, hogy a szem koordináta vektorát beszorozzuk balról a vetítési mátrixszal.
       A vertex normalizált eszköz koordinátáit pedig a következõképpen kapjuk:

                                            (xd, yd, zd) = (xc/wc, yc/wc, zc/wc),

azaz a vetítés koordinátákat leosztjuk a wc homogén koordinátával.

Normál transzformáció

    A normálisok a fényszámításokban (is) vesznek részt. A normálisokat nem úgy transzformáljuk, mint a vertexeket vagy a pozíció vektorokat. Matematikailag jobb, ha a normálisokat nem vektornak, hanem a vektorra merõleges síknak tekintjük. Ekkor a normálisokra vonatkozó transzformációs szabályok a merõleges síkok transzformáció szabályai.
    Egy homogén síkot egy (a, b, c, d) sorvektorral definiálhatunk, ahol az a, b, c, d komponensek legalább egyike nem nulla. Ha q egy nemnulla valós szám, akkor (a, b, c, d) és (qa, qb, qc, qd) ugyanazt a síkot reprezentálják. Egy (x, y, z, w) pont pontosan akkor van az (a, b, c, d) síkon, ha ax+by+cz+dw = 0. ( ha w = 1, akkor ez egy euklideszi sík) Ahhoz, hogy egy euklideszi síkot reprezentáljunk, nem lehet az a, b, c ( a sík normálvektora: (a, b, c)) komponensek mindegyike 0. Ha mind 0, akkor (0, 0, 0, d) egy végtelen távoli síkot reprezentál, amely az összes végtelen távoli pontot tartalmazza.
    Ha p egy homogén sík, v pedig egy homogén vertex, akkor a "v a p síkon fekszik" megállapítás matematikailag a következõt jelenti: p*v = 0, ahol p*v egy szokásos mátrix(vektor) szorzás mûvelet. Ha M egy nemszinguláris vertex transzformáció, akkor p*v = 0 ekvivalens a p*M ^(-1)*M*v = 0 egyenlettel, tehát M*v a p*M^(-1) síkon fekszik. Ezért, p*M^(-1) az  M transzformáció utáni képe a síknak.
 

Vetítések

    Ha a háromdimenziós objektumokat meg akarjuk jeleníteni a monitor képernyõjén, akkor ezeket a háromdimenziós modelltérbõl egy kétdimenziós nézetre kell leképezni. Ezért a Számítógépes grafikában kiemelt jelentõségû transzformációk a vetítések.
 A vetítés dimenziócsökkentõ mûvelet, tehát olyan transzformáció, amely n-dimenziós objektumokat kisebb dimenziós terekbe visz át. A vetítés eredménye a vetület, ami egy térbeli síkon, a vetítési síkon képzõdik. A tárgy- és képpontokon átmenõ egyenest vetítõsugárnak nevezzük. Az egyes tárgypontok képe a vetítõsugár döféspontja a vetítési síkkal.
 Általában kétféle vetítési típus használatos: párhuzamos, illetve perspektív vetítés.
 Párhuzamos vetítés esetén a vetítõsugarak párhuzamosak, ilyenkor csupán a vetítési irány van definiálva; perspektív vetítés esetén a vetítõsugarak mindegyike áthalad egy vetítési középponton, a centrumponton (szempozíció). A perspektív vetítés az objektumok realisztikus ábrázolását teszi lehetõvé, ilyenkor a távolabbi objektumok kisebbnek tûnnek, a vetítési síkkal nem párhuzamos egyenesek egy pont felé tartanak. Párhuzamos vetítés esetén az eredetileg párhuzamos egyenesek párhuzamosak maradnak. Ezt a fajta vetítést a mérnöki tervezésben alkalmazzák, mégpedig azért, mert tudunk olyan párhuzamos vetítést specifikálni, ahol mérhetõek a távolságok és a szögek.
Perspektív vetítés esetén a látótér tulajdonképpen egy végtelen piramisként képzelhetõ el, amelynek csúcsa a nézõpont, vagy szem. Az OpenGL-ben azért, hogy a túl közeli és távoli koordinátákkal ne kelljen foglalkozni, a látóteret elülsõ és hátsó síkokkal (vágósíkok) korlátozhatjuk, így a különbözõ megjelenítési eljárásokban csak ezt a korlátozott térrészt vesszük figyelembe. Tehát az OpenGL-ben egy csonkagúla fogja a perspektív vetítés látóterét reprezentálni, amelyet az elülsõ és hátsó vágósíkokkal adunk meg.
 Párhuzamos vetítés esetén a látótér egy végtelen hasáb, amelyet itt is vágósíkokkal korlátozhatunk, így az OpenGL-ben a párhuzamos vetítés látótere egy téglatest. Az OpenGL-ben a párhuzamos vetítés azon speciális típusát használhatjuk, ahol a vetítési sík merõleges a z-tengelyre, és a vetítési sík normálisa párhuzamos a vetítési iránnyal, azaz az ortogonális vetítést.
 Az OpenGL-ben mindkét fajta vetítést úgy specifikálhatjuk, hogy megadjuk a látótér nagyságát és alakját.
 

Világítás/Lighting

    Az OpenGL a megjelenítés elõtt minden pixel színét kiszámítja, a kiszámolt színértékeket a képpufferben tárolja el. A felmerülõ számítások egy része attól függ, milyen megvilágítást alkalmazunk, és hogy az objektumok ezen megvilágítás fényét hogyan tükrözik illetve nyelik el. Az OpenGL-ben lehetõség van a fényforrások és objektumok tulajdonságainak manipulálására.
    Az OpenGL világítási modellben a fényt több, egyenként ki-, illetve bekapcsolható fényforrás határozza meg. A fényforrásoknak csak akkor van hatása, ha vannak olyan felületek, melyek a fényt visszatükrözik, vagy elnyelik. Egy anyagnak lehet saját fénye is, a bejövõ fényt szétszórhatja minden irányban, és tükrözheti a bejövõ fény egy részét egy bizonyos irányba akár egy tükör vagy más tükrözõdõ felszín.
    Az OpenGL világítási modellben a fénynek három független komponense van: ambient, diffúz és spekuláris.

     Szórt háttérvilágítás (ambient light)

    Ebben a modellben az objektumok egyenletesen, minden irányból kapnak fényt. Hatása a nappali fényviszonyoknak felel meg erõsen felhõs égbolt esetén. A számítógépes grafikában azért van rá szükség, hogy a felhasználó az ábrázolt jelenet összes objektumának a megvilágítását szabályozhassa. Ebben a modellben nincs fényforrás, az objektumok "saját" fényüket bocsájtják ki. Ez megfelel annak, hogy a jelenetet egy irányfüggetlen, szórt fény világítja meg.

    Diffúz fényvisszaverõdés (diffuse light)

    A diffúz fényvisszaverõdés a matt felületek jellemzõje. Ekkor a megvilágított felület minden irányban ugyanannyi fényt ver vissza.

    Fényvisszaverõdés fényes és csillógó felületekrõl (specular light)

    A sima felületekre általában az a jellemzõ, hogy rajtuk fényes foltokat (specular highlight) is látunk, melyek helye nézõpontunkkal együtt változik. Ezek a felületek bizonyos irányokban visszatükrözik a fényforrásokat. Ekkor a matt felületekre jellemzõ diffúz és a tökéletesen (ideálisan) tükrözõ felületekre jellemzõ visszaverõdés közti átmeneti esetet kell modelleznünk.

Anyag színek

    Az OpenGL aszerint a megközelítés szerint dolgozik, miszerint egy anyag színe a bejövõ fényben szereplõ vörös, zöld és kék fény arányától függ. Például egy tökéletesen piros labda minden bejövõ piros fényt visszatükröz, és minden zöld és kék fényt elnyel, amely eltalálja õt. Ha a labdát fehér fényben nézzük (a fényt egyenlõ vörös, zöld és kék komponensekbõl kikeverve), akkor egy piros labdát látunk; ha azonban tiszta zöld fénnyel világítjuk meg a labdát, az feketének tûnik (a zöld szín teljesen elnyelõdik, és nincs visszatükrözõdõ fény). Akárcsak a fénynek, az anyagoknak is különbözõ ambient, diffúz és spekuláris színei vannak, amelyek meghatározzák az anyag ambient, diffúz és spekuláris tükrözõdését. Egy anyag ambient tükrözõdése összefüggésben van a bejövõ fény ambient komponensével, a diffúz tükrözõdése a bejövõ fény diffúz komponensével, ... . Az ambient és diffúz tükrözõdések határozzák meg az anyag színét, ezek többnyire hasonlóak vagy megegyezõek. A spekuláris tükrözõdés általában fehér vagy szürke.
    Az ambient, diffúz és spekuláris színek mellett, az anyagoknak emisszív színei is vannak, amelyek a világító objektumok fényét szimulálják, azaz egy anyag emisszív színe az anyag saját fényének a színe. Az OpenGL megvilágítási modellben egy anyag emisszív színe intenzitást ad az objektumnak, de nincsenek rá hatással a fényforrások, és a világító objektum sincs hatással a többi objektumra.

A fények és anyagok RGB értékei

    A specifikált fények szín komponensei némiképp különböznek az anyagokétól. Egy fény esetén, az értékek a teljes intenzitás százalékos kifejezései minden színre. Ha a fény színének mind az R, G és B komponense 1.0, akkor a fény a legfehérebb fehér. Ha az értékek mindegyike 0.5, a fény még mindig fehér, de csak fél intenzitással, így az szürkének tûnik.
    Az anyagok számára, az értékek a színek tükrözõdési arányait specifikálják. pl. ha R = 1.0, G = 0.5 és B = 0.0, akkor az anyag minden bejövõ vörös fényt és a zöld fény 50%-át veri vissza, viszont minden kék fényt elnyel. Más szavakkal, ha egy fényforrás szín komponensei (LR,LG,LB) egy anyag megfelelõ fény komponensei pedig (MR,MG,MB), akkor minden más tükrözõdési effekttõl eltekintve a szemünkbe érkezõ fény: (LR*MR,LG*MG,LB*MB).

Megvilágított képek készítése

A következõ lépések kellenek ahhoz, hogy a képünkhöz világítást adjunk:

    1. minden objektum minden vertexéhez specifikálnunk kell normál vektort. Ezen normál vektorok határozzák meg az
        objektum irányát a fényforráshoz viszonyítva
    2. egy vagy több fényforrás létrehozása, kiválasztása és pozicionálása
    3. egy megvilágítási modell létrehozása és kiválasztása
    4. az objektumok anyagi tulajdonságainak definiálása
 

-> következõ oldal
<- elõzõ oldalra
<--fõoldalra