„Számítógépes grafika házi feladat tutorial” változatai közötti eltérés
aNincs szerkesztési összefoglaló |
Hozzáadtam a 'Koordináta rendszerek' részt |
||
| 265. sor: | 265. sor: | ||
</div> | </div> | ||
==Projekciós mátrixok, transzformációk== | == A második házihoz szükséges elmélet == | ||
=== Koordináta rendszerek === | |||
* Az első háziba valószínűleg feltűnt, hogy a pontok NDC (normalizált eszköz koordináta) megadása nem túl kényelmes, még akkor se ha, a világnak mindig ugyan azt a részét nézzük. De mit tegyük akkor, ha a képzeletbeli kamera amivel "lefényképezzük" a jelenetet mozoghat, sőt akár még forghat is. | |||
* Az OpenGL kitalálónak az ötlete az volt erre, hogy a kamera mindig maradjon egyhelyben, de ha pl. balra akarnánk forgatni, akkor helyette inkább a világ forogjon jobbra, a kamera maradj ugyanott, és ezzel ugyan azt a hatást érjük el. Persze nem kell minden egyes pontot nekünk elforgatni, ezt rábízhatjuk az OpenGL-re is, hogy mindig mielőtt rajzolna, azelőtt végezzen el valamilyen transzformációt a pontokat amiket kapott. | |||
** A lineáris (és affin) transzformációkat a legkényelmesebb a mátrixuk segítségével tudjuk megadni, több egymás utáni transzformáció pedig egyszerűen a mátrixok szorzatát jelenti. Viszont fontos megjegyezni, hogy 3D-ben az eltolás nem lineáris transzformáció, és nem is lehet mátrixal felírni. Ennek kiküszöbölésére használhatunk 4D-be w = 1 koordinátával beágyazott 3D-s koordináta rendszert, ahol az eltolás is egy lineáris trafó. | |||
** Az OpenGL két mátrixot ad nekünk, amiknek módosíthatunk, és amivel az összes kirajzolandó pontot mindig beszorozza helyettünk. Az egyik a GL_MODELVIEW, a másik a GL_PROJECTION. A GL_MODELVIEW-val mozgathatunk objektumokat egymáshoz képest, és itt tudjuk megadni, hogy hogyan kell transzformálni a világot, hogy az origóban lévő, -z irányba néző képzeletbeli azt lássa, amit meg akarunk jeleníteni. A GL_PROJECTION pedig azt adja meg, hogy a kamerával hogyan kell fényképzni. | |||
*** Két dimezióban a két mátrix különválasztása gyakorlatilag fölösleges, ennek csak 3D-be lesz szerepe, majd a megvilágításkor. 2D-ben a kényelmesebb a GL_PROJECTION-ra bízni a kamera mozgatást is, és a GL_MODELVIEW-t pedig meghagyni csak az objektumok közötti transzformációk leírására. | |||
* Projekció 2D-ben: a fényképezés módja nagyon egyszerű, egyszerűen eldobjuk a 'z' koordinátát, és az x-y pozició alapján rajzolunk. Vagy legalábbis ezt csináltuk eddig, de az NDC nem volt kényelmes. Itt viszont lehetőséget kapunk saját koordinátarendszer megválasztására, ahol az egység lehet pl. 1 méter, és a kamera pedig mondjuk követhet egy karaktert egy játékban. | |||
* Példaprogram: [http://pastebin.com/zV32Zg1f Sidescroller] | |||
<br/> <syntaxhighlight lang="c"> | |||
// Megmondjuk a OpenGL-nek, hogy ezután a projekciós mátrixot | |||
// akarjuk módosítani a transzformációs mátrix műveletekkel. | |||
glMatrixMode(GL_PROJECTION); | |||
// Egység mátrixot töltük be a jelenlegi vetítési mátrix helyére. | |||
glLoadIdentity(); | |||
// Ez egy olyan merőleges (Orthogonális) vetítés, aminek eredménye képpen a karakter | |||
// az x tengely mentén középen lesz, és 10 egység (méter) széles részt látunk a világból | |||
// míg az y tengely mentén a képernyő alsó egy ötödében lesz, és itt is 10 egység magas | |||
// részt látunk. | |||
gluOrtho2D( | |||
stickman.pos.x - 5, stickman.pos.x + 5, | |||
stickman.pos.y - 2, stickman.pos.y + 8 | |||
); | |||
</syntaxhighlight> <br/> | |||
Az eredménye: | |||
<div style="text-align:left;margin:0px auto;"> | |||
http://i.imgur.com/6WgP4iC.gif | |||
</div> | |||
== Régi wikiről áthozott rész, frissitésre szorul == | |||
=== Projekciós mátrixok, transzformációk === | |||
* Az OpenGL a megjelenítő csővezetékben két transzformációs mátrixot használ, ezek a ModelView és a Projection mátrixok. A keretrendszer nem módosítható részében mindkét mátrixba az egység mátrixot töltik a glLoadIdentity() függvény segítségével. Ez alkotja a már említett 2D orthogonális vetítést (-1,+1) méretű koordináta-rendszerben. | * Az OpenGL a megjelenítő csővezetékben két transzformációs mátrixot használ, ezek a ModelView és a Projection mátrixok. A keretrendszer nem módosítható részében mindkét mátrixba az egység mátrixot töltik a glLoadIdentity() függvény segítségével. Ez alkotja a már említett 2D orthogonális vetítést (-1,+1) méretű koordináta-rendszerben. | ||
| 324. sor: | 358. sor: | ||
</pre> | </pre> | ||
==Görbék== | === Görbék === | ||
* A görbékről igen sok anyag található a könyvben, diákon, még itt a wiki-n is, így csak néhány hasznos tippet és programozás-technikai dolgot írok itt le | * A görbékről igen sok anyag található a könyvben, diákon, még itt a wiki-n is, így csak néhány hasznos tippet és programozás-technikai dolgot írok itt le | ||
* A görbe egy elvont matematikai fogalom, a kirajzoláskor nem használjuk! A görbéket vektorizáljuk (vonalakra bontjuk), és ezeket a törött-vonalakat rajzoltatjuk ki az openGL segítségével. | * A görbe egy elvont matematikai fogalom, a kirajzoláskor nem használjuk! A görbéket vektorizáljuk (vonalakra bontjuk), és ezeket a törött-vonalakat rajzoltatjuk ki az openGL segítségével. | ||
| 331. sor: | 365. sor: | ||
* A görbék kontrollpontjainak megadása nem egyszerű, a rajzolás és a tesztelés egyszerűbbé tehető, ha a görbénket egy másik program segítségével "megtervezzük". Ilyen Java-applet-eket könnyen találhatunk az Interneten, elég rákeresni a "<görbenév> applet" kifejezésre, és máris grafikus felületen kattingathatjuk össze a görbénket. | * A görbék kontrollpontjainak megadása nem egyszerű, a rajzolás és a tesztelés egyszerűbbé tehető, ha a görbénket egy másik program segítségével "megtervezzük". Ilyen Java-applet-eket könnyen találhatunk az Interneten, elég rákeresni a "<görbenév> applet" kifejezésre, és máris grafikus felületen kattingathatjuk össze a görbénket. | ||
==Időzítés, animáció== | === Időzítés, animáció === | ||
* Az animáció kezelésére és az újrarajzolás elhelyezésére (a Gordiuson történő hibás működések miatt) sokféle megoldás született. Én a szerintem leglogikusabb elrendezést írom itt le, amely garantáltan működik otthon és a Gordiuson is. Az animáció elve a következő: | * Az animáció kezelésére és az újrarajzolás elhelyezésére (a Gordiuson történő hibás működések miatt) sokféle megoldás született. Én a szerintem leglogikusabb elrendezést írom itt le, amely garantáltan működik otthon és a Gordiuson is. Az animáció elve a következő: | ||
** Létezik a világ modellje, gyakorlatilag a globális változóink. Azért globálisak, hogy elérhetőek legyenek a különböző GLUT függvényekből. A modellt csak az események, azaz az onKeyboard, onMouse és onIdle függvények módosíthatják. | ** Létezik a világ modellje, gyakorlatilag a globális változóink. Azért globálisak, hogy elérhetőek legyenek a különböző GLUT függvényekből. A modellt csak az események, azaz az onKeyboard, onMouse és onIdle függvények módosíthatják. | ||
| 365. sor: | 399. sor: | ||
*** Pontosan ezt csinálja az fmod függvény is: lebegőpontos osztás maradékát adja vissza. Így fmod(6.8, 2.0) = 0.8. | *** Pontosan ezt csinálja az fmod függvény is: lebegőpontos osztás maradékát adja vissza. Így fmod(6.8, 2.0) = 0.8. | ||
==Tesszelláció== | === Tesszelláció === | ||
* A tesszelláció a világban található objektumok felbontása háromszögekre. Hogy miért van erre szükség? Mert az openGL csak vonalakat és háromszögeket képes kirajzolni, minden test ezekből épül fel. | * A tesszelláció a világban található objektumok felbontása háromszögekre. Hogy miért van erre szükség? Mert az openGL csak vonalakat és háromszögeket képes kirajzolni, minden test ezekből épül fel. | ||
* '''2D házik''' | * '''2D házik''' | ||
| 377. sor: | 411. sor: | ||
** TODO: tipikus testek | ** TODO: tipikus testek | ||
==Sugárkövetés== | === Sugárkövetés === | ||
* A sugárkövetés házinak nem sok köze van az openGL-hez, inkább sok 3D-s koordináta-geometria és némi fizika szükséges hozzá. | * A sugárkövetés házinak nem sok köze van az openGL-hez, inkább sok 3D-s koordináta-geometria és némi fizika szükséges hozzá. | ||
* A sugárkövetés nagy hátránya, hogy mivel mi írjuk a "renderelő motort", így igen nehéz a tesztelés és debuggolás, hiszen egy apró hiba miatt is előfordulhat hogy a képen semmit sem látunk. Könnyítsük meg a saját dolgunkat azzal, hogy egy papírra lerajzoljuk a testek elhelyezkedését, többször is ellenőrizzük a tengelyek irányát. Ha sehogy nem azt látjuk amit szeretnénk, írjuk ki a változóink értékét a konzolra, és úgymond szövegesen teszteljük a programot. | * A sugárkövetés nagy hátránya, hogy mivel mi írjuk a "renderelő motort", így igen nehéz a tesztelés és debuggolás, hiszen egy apró hiba miatt is előfordulhat hogy a képen semmit sem látunk. Könnyítsük meg a saját dolgunkat azzal, hogy egy papírra lerajzoljuk a testek elhelyezkedését, többször is ellenőrizzük a tengelyek irányát. Ha sehogy nem azt látjuk amit szeretnénk, írjuk ki a változóink értékét a konzolra, és úgymond szövegesen teszteljük a programot. | ||
===OpenGL rész=== | ==== OpenGL rész ==== | ||
* Sugárkövetésnél OpenGL függvényt csak a kész kép kirajzolásához használunk, a következő módon: | * Sugárkövetésnél OpenGL függvényt csak a kész kép kirajzolásához használunk, a következő módon: | ||
<pre> | <pre> | ||
| 393. sor: | 427. sor: | ||
* A 600*600 pixel nem véletlen, a keretben ez az ablak fixen megadott mérete. | * A 600*600 pixel nem véletlen, a keretben ez az ablak fixen megadott mérete. | ||
===Osztályok=== | ==== Osztályok ==== | ||
* Megkönnyítjük a saját dolgunkat, ha az alábbi osztályokat létrehozzuk, és azokhoz megfelelő operátorokat készítünk: | * Megkönnyítjük a saját dolgunkat, ha az alábbi osztályokat létrehozzuk, és azokhoz megfelelő operátorokat készítünk: | ||
** '''Vector/Coordinate/Point''' | ** '''Vector/Coordinate/Point''' | ||
| 408. sor: | 442. sor: | ||
** '''Mesh''' - háromszögekből álló test, mely egy közös metszéspont kereső függvényt definiál, az összes háromszög metszéspontjai közül azt adja vissza, amelyiknek legkisebb a távolsága (de még pozitív), tehát amit legelőször talál el a sugár. | ** '''Mesh''' - háromszögekből álló test, mely egy közös metszéspont kereső függvényt definiál, az összes háromszög metszéspontjai közül azt adja vissza, amelyiknek legkisebb a távolsága (de még pozitív), tehát amit legelőször talál el a sugár. | ||
===Metszéspontok, önárnyékolás és az EPSILON=== | ==== Metszéspontok, önárnyékolás és az EPSILON ==== | ||
<div id="AnchorOnarnyekolas"></div> | <div id="AnchorOnarnyekolas"></div> | ||
* TODO | * TODO | ||
===Sugár indítások, egy és kétirányú sugárkövetés=== | ==== Sugár indítások, egy és kétirányú sugárkövetés ==== | ||
* TODO: egy/kétirányú: ... | * TODO: egy/kétirányú: ... | ||
* Az indítandó sugarak létrehozásához nekünk kell definiálnunk a perspektivikus kamerát, hasonlóan ahhoz, ahogy az openGL 3D perspektivikus leképzését definiáljuk: TODO: ... | * Az indítandó sugarak létrehozásához nekünk kell definiálnunk a perspektivikus kamerát, hasonlóan ahhoz, ahogy az openGL 3D perspektivikus leképzését definiáljuk: TODO: ... | ||
===Színek, fények, optikai modellek=== | ==== Színek, fények, optikai modellek ==== | ||
<div id="AnchorToneMap"></div> | <div id="AnchorToneMap"></div> | ||
* Tone Map | * Tone Map | ||
| 425. sor: | 459. sor: | ||
*** Egyik fontos eleme, hogy figyelembe veszi a három színkomponens fényességének eltérését, és a következő kísérleti alapon megállapított intenzitásképletet használja: ''Y = 0.2126 R + 0.7152 G + 0.0722 B'' | *** Egyik fontos eleme, hogy figyelembe veszi a három színkomponens fényességének eltérését, és a következő kísérleti alapon megállapított intenzitásképletet használja: ''Y = 0.2126 R + 0.7152 G + 0.0722 B'' | ||
==3D alapok== | === 3D alapok === | ||
<div id="AnchorZFighting"></div> | <div id="AnchorZFighting"></div> | ||
* TODO: kamera, Z-buffer VS. clipping pane, árnyalás VS. normálvektorok, glut tesszellátorok | * TODO: kamera, Z-buffer VS. clipping pane, árnyalás VS. normálvektorok, glut tesszellátorok | ||
==3D extrák== | === 3D extrák === | ||
* TODO: fények, csillanás, textúrázás | * TODO: fények, csillanás, textúrázás | ||
== Hibakezelés == | === Hibakezelés === | ||
-- [[BlackGhost|BlackGhost]] - 2011.04.05. | -- [[BlackGhost|BlackGhost]] - 2011.04.05. | ||