Mátrixok

- A glMatrixMode, glLoadIdentity, glLoadMatrix és glMultMatrix parancs
- A nézeti transzformáció beállítása, a gluLookAt parancs
- Lineáris transzformációk
- A viewport definiálása
- Vetítési mátrixok
- Mátrix vermek

Ez a fejezet olyan transzformációkról szó. amelyek elengedhetetlenek a számítógépes grafikában. Transzformációval lehet leírni például a 3D koordináták 2D koordinátákká végzõ dimenziócsökkentõ mûveletet, a vetítést, vagy projekciót. Lineáris transzformációk az eltolások, forgatások illetve nagyítások. Ezek a transzformációk tulajdonképpen nem is közvetlenül az objektumokat módosítják, hanem a koordináta-rendszert, amelyben az objektumok elhelyezkednek. Három fõ transzformáció van, amely részt vesz a specifikált vertexek képernyõre transzormálásában: nézeti (viewing), modellezési (modelling) illetve vetítési (projection) transzformáció. A nézeti transzformáció a kamera vagy szem (eye) pozicionálását és irányának megadását
jelenti. A modellezési transzformáció a modell vagy objektumok pozicionálását és orientálását foglalja magába. A nézeti transzformációnak meg kell elõznie a modellezési transzformációt az OpenGL kódban.
Az OpenGL transzformációk áttekintése:

Transzformáció Alkalmazás

Nézeti transzformáció | specifikálja a kamera helyzetét
Modellezési transzformáció | objektumok megfelelõ helyre mozgatása
Modell-nézet transzformáció | az elõzõ két transzformációt foglalja magába
Vetítési transzformáció | vágás és látótérbe méretezés
Ablak-transzformáció | az ablakba méretezés

A glMatrixMode, glLoadIdentity, glLoadMatrix és glMultMatrix parancs

Az OpenGL-ben mind a vetítési (projekció), mind a modell-nézet mátrix módosítható illetve beállítható. Az érvényes mátrix módot a

void glMatrixMode( enum mode );

eljárással lehet beállítani, ahol a mode a GL_TEXTURE, GL_MODELVIEW, GL_COLOR illetve GL_PROJECTION szimbolikus konstansok valamelyike lehet. A vetítési mátrix a szem koordináta rendszer (eye coordinate system) és a vetítés koordináta rendszer (clip coordinate system) közötti transzformációt írja le. Ha az érvényes mátrix mód a GL_MODELVIEW, akkor a mátrix mûveletek a modell-nézet mátrixra vannak hatással (magyarul ezen mátrix manipulálásával tudunk geometriai transzformációkat (forgatás-glRotate, eltolás-glTranslate, nagyítás-glScale) végezni az objektumokon), ha GL_PROJECTION, akkor a vetítési mátrixra (tehát így tudunk vetítést megadni). A két alapvetõ eljárás, amellyel az aktuális mátrixot inicializálhatjuk, a
void glLoadMatrix{fd}( T m[16] );
void glMultMatrix{fd}( T m[16] );

A glLoadMatrix argumentuma egy 16 elemû vektor, amely egy 4×4-ex mátrixot reprezentál úgy, hogy 16 lebegõpontos számot tárol oszlopfolytonosan(!!). A glLoadMatrix az érvényes mátrixot helyettesíti a megadott mátrixszal.
A glMultMatrix ugyanígy mûködik, de nem helyettesíti az érvényes mátrixot, hanem beszorozza azt balról a megadott mátrixszal. Tehát, ha C az eredeti mátrix, M pedig a glMultMatrix argumentuma, akkor

C' = C*M,

és C' az új mátrix.
A

void glLoadIdentity(void);

eljárás egyenértékû azzal, mint ha meghívnánk a glLoadMatrix-ot az egységmátrixszal. Tehát a glLoadIdentity() parancs meghívása után az érvényes mátrix az egységmátrix lesz.

A gluLookAt parancs

Az OpenGL alapból nem tartalmaz nézeti transzformációt beállító eljárásokat. A szem mindig a (0, 0, 0) koordinátákban van. Ahhoz, hogy a kamera mozgását érzékeltessük, az objektumokat kell a kamera transzformáció inverzével elmozgatni.
A GLU library azonban tartalmaz egy olyan parancsot, mellyel nézeti transzformációt végezhetünk.

void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery,
Gldouble centerz, GLdouble upx, GLdouble upy, GLdouble upz);

paranccsal a nézeti transzformációt állíthatjuk be.(eyex, eyey, eyez) specifikálják a szem pozícióját.
(centerx, centery, centerz) egy referenciapontot specifikál, ahová a szem néz; (upx, upy, upz) egy felfelé mutató vektor (up-vektor,VUP). A gluLookAt eljárás kiszámítja a megadott kamera transzformáció inverzét, majd megszorozza
a kapott inverz transzformációs mátrixszal az érvényes mátrixot, ezért arra ügyelni kell, hogy az érvényes mátrix mód a
GL_MODELVIEW legyen.

pl.:

gluLookAt(0.0,0.0,2.0,0.0,0.0,0.0,0.0,1.0,0.0);

Lineáris transzformációk

A lineáris transzformációk a következõ eljárásokkal specifikálhatók (az itt felsorolt parancsok a MODELVIEW mátrixot módosítják, tehát pl. egy glRotate parancs specifikál egy transzformációs mátrixot, amely forgatást végez, majd ezzel beszorozza az érvényes MODELVIEW mátrixot)
A

void glRotate{fd}( T a, T x, T y, T z );

eljárásban az a adja meg, hogy hány fokkal forgatunk; a kiszámolt mátrix egy óramutató járásával ellentétes forgatást specifikál az (x, y, z)-vel megadott tengely körül.

pl.: a glRotated(45, 1.0, 0.0, 0.0) egy 45 fokos forgatást specifikál az x tengely körül
a glRotated(12.5, 0.0, 0.0, 1.0) egy 12.5 fokos forgatást specifikál a z tengely körül
A

void glTranslate{fd}( T x, T y, T z );

argumentumai az eltolás vektort adják meg: ( x, y, z ).

pl.: a glTranslated( 50, 0, 0 ) az x-tengely mentén 50 egységgel való eltolást specifikál
A

void glScale{fd}( T x, T y, T z );

eljárás általános skálázást végez az x, y, z tengely mentén.

pl.: a glScaled(0.5, 0.5, 0.5) egy 0.5-szörös uniform nagyítást végez

A viewport definiálása

A viewport az az ablakon belüli rész, ahová rajzolunk, tehát a viewport transzformációval adjuk meg a létrejövõ kép méretét. A viewport általában maga az ablak, de elképzelhetõ az is, hogy a viewport az ablaknak csupán egy része. A következõ két ábra közül az egyik olyan viewportot ábrázol, amely az egész ablakot lefedi, a másiknál a viewport a létrehozott ablak bal alsó sarkánál helyezkedik el.

Az aktuális viewportot a

void glViewport(int x, int y, GLsizei width, GLsizei height);

eljárással specifikálhatjuk. Az eljárás egy téglalapot definiál az OpenGL ablakba, ahová rajzolni szeretnénk. Az (x, y) paraméterek specifikálják a viewport bal alsó sarkát, width és height pedig a viewport téglalap méretét. Alapértelmezésben a paraméterek a (0, 0, winWidth, winHeight) értékeket veszik fel, ahol winWidth és winHeight az ablak méretei.

pl.: glViewport(0, 0, w, h) esetén ha az ablak szélessége w, magassága pedig h, akkor a viewport az ablak lesz.

Vetítési mátrixok

Az OpenGL-ben párhuzamos (ortografikus) és perspektivikus vetítést is specifikálhatunk. Itt némi kiegészítésre van szükség a vetítésekkel kapcsolatosan: a két alapvetõ vetítési fajtán belül még igen sokféle különbözõ vetítést meg lehet adni; perspektív vetítésnél a vetítéseket az elsõdleges távlatpontok száma szerint osztályozzuk, párhuzamos vetítés esetén pedig a vetítési irány és a vetítési sík egymáshoz való viszonya szerint. Jelen honlapon ha párhuzamos vetítésrõl van szó, akkor mindig olyan párhuzamos vetítésre gondolunk, 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 ortografikus vetítés egy speciális esete). A vetítéseket úgy adjuk meg, hogy megadjuk a látótér nagyságát és alakját. Ami a látótéren belülre esik, az fog a képernyõn látszani.

A

void glOrtho( double left, double right, double bottom, double top, double near, double far );

eljárással a párhuzamos vetítés látóterét specifikálhatjuk. left és right adják meg a baloldai és jobboldali függõleges vágósíkok koordinátáit. bottom és top az alsó és felsõ vízszintes vágósíkok koordinátái. near és far adják meg a közeli és távoli vágósíkok távolságát a szemtõl. A (left, bottom, -near) és a (right, top, -near) specifikálják tehát a közeli vágósík pontjait, amelyek ráfeszülnek az ablak bal alsó és jobb felsõ sarkaira ( feltételezve, hogy a szem a (0, 0, 0) pontban van). far adja meg a távoli vágósík távolságát a szemtõl.
Tehát a közeli vágósík ablakba esõ részének bal alsó sarka: (left, bottom, -near), a jobb felsõ sarka:
(right, top, -near). A távoli vágósík ablakba esõ részének bal alsó sarka: (left, bottom, far), jobb felsõ sarka:
(right, top, far).
Ha kétdimenziós objektumokat akarunk rajzolni, akkor a
void gluOrtho2D(double left, double right, double bottom, double top);

eljárással is specifikálhatjuk a vetítési mátrixot. Ekkor a vágási téglalap egyszerûen a (left, bottom, right, top) koordinátákkal megadott téglalap.
A glOrtho (gluOrtho2D) megszorozza az aktuális projekciómátrixot a specifikált mátrixszal és ez lesz az új projekciómátrix. Ebben az esetben a látótér egy téglalap, amelyre példa:

2. ábra

pl.: a glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0) egy párhuzamos vetítést specifikál, ahol a közeli vágósík(azon része, mely a látótérbe esik) bal alsó sarkának koordinátái (0.0, 0.0, -1.0) , jobb felsõ sarkának koordinátái (1.0, 1.0, -1.0); a távoli vágósík bal alsó sarkának koordinátái (0.0, 0.0, 1.0), jobb felsõ sarkának koordinátái (1.0, 1.0, 1.0). Azaz mind a közeli, mind a távoli vágósík 1.0 távolságra van a vetítési síktól.

A

void glFrustum( double left, double right, double bottom, double top, double znear, double zfar );

eljárással a perspektív vetítés látóterét specifikálhatjuk. left és right adják meg a baloldali és jobboldali függõleges vágósíkok koordinátáit. bottom és top az alsó és felsõ vízszintes vágósíkok koordinátái. znear és zfar adják meg a közeli és távoli vágósíkok távolságát a szemtõl. A (left, bottom,- znear) és (right, top,- znear) specifikálják tehát a közeli vágósík pontjait, amelyek ráfeszülnek az ablak bal alsó és jobb felsõ sarkaira. zfar adja meg a távoli vágósík távolságát a szemtõl. (itt is feltételezzük, hogy a szem a (0, 0, 0) pontban van).
Lehetõség van a perspektív vetítési mátrix egy szemléletesebb specifikációjára is, mégpedig a
void gluPerspective(double fovy, double aspect, double near, double far);

eljárás segítségével, amely szimmetrikus látóteret specifikál. fovy adja meg a látótér szögét az x-z sík irányában, aspect a vágási téglalap szélességének és magasságának arányát, near és far pedig a vágósíkok távolságát.

A glFrustum megszorozza az aktuális projekció mátrixot a specifikált mátrixszal és ez lesz az új projekció mátrix. Ennél a vetítésnél a látótér egy csonkagúla, amely a következõképpen néz ki:

3.ábra

4.ábra

pl.: a glFrustum(0.0, 1.0, 0.0, 1.0, 1.0, 3.0) egy perspektivikus vetítést specifikál, ahol a közeli vágósík (azon része, mely a látótérbe esik) bal alsó sarkának koordinátái (0.0, 0.0, -1.0), jobb felsõ sarkának koordinátái (1.0, 1.0, -1.0); a távoli vágósík bal alsó sarkának koordinátái (0.0, 0.0, -3.0), jobb felsõ sarkának koordinátái (1.0, 1.0,- 3.0). Azaz a közeli vágósík 1.0 távolságra, a távoli vágósík pedig 3.0 távolságra van a szemtõl.

Mátrix vermek

Minden mátrix mód számára van egy mátrix verem. Az érvényes mátrix minden módban a verem tetején lévõ mátrix. A mûveletek:

void glPushMatrix( void );
void glPopMatrix( void );

A glPushMatrix és glPopMatrix az érvényes mátrix módnak megfelelõ mátrixokkal dolgoznak. Kezdetben minden veremben egy mátrix van, mégpedig az egységmátrix. A kezdõ mátrix mód a MODELVIEW mód.A mátrix veremmûveletekkel lehetõvé válik az egyes mátrixok elmentése, hogy késõbb, ha szükségünk van rájuk, akkor újra használni tudjuk. A mátrix veremmûveleteket többnyire akkor használjuk, amikor olyan objektumot akarunk pl. animálni, mely több egyszerûbb objektumból épül fel, és az egyes részeket eltérõ módon akarjuk mozgatni/transzformálni. Például, ha rajzolunk két kockát, és az egyiket forgatjuk a z-tengely mentén az óramutató járásával ellentétes irányba, a másikat pedig az óramutatóval megegyezõ irányba forgatjuk, akkor ezt úgy tudjuk megoldani, hogy a két kockára két különbozõ transzformációs mátrixunk van.

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