Mátrixok

    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

           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

            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.

            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