„Számítógépes grafika házi feladat tutorial” változatai közötti eltérés
a Kiszedtem pár rossz linket |
a Kiszedtem pár indokolatlan, inkonzisztens linket |
||
| 1. sor: | 1. sor: | ||
{{GlobalTemplate|Infoalap|SzgGrafHaziTutorial}} | {{GlobalTemplate|Infoalap|SzgGrafHaziTutorial}} | ||
{{Vissza|Számítógépes_grafika_és_képfeldolgozás | {{Vissza|Számítógépes_grafika_és_képfeldolgozás}} | ||
Ez a tutorial nem helyettesíti az órán leadott tananyagot, de sokat segíthet a házi megírásában, ha esetleg nem volt időd órára járni, vagy valamelyik előadás nem volt teljesen világos. A leírás célja, hogy segítsen az alapvető buktatók elkerülésében, valamint választ adjon az évről-évre a listán újra és újra elhangzó kérdésekre. | Ez a tutorial nem helyettesíti az órán leadott tananyagot, de sokat segíthet a házi megírásában, ha esetleg nem volt időd órára járni, vagy valamelyik előadás nem volt teljesen világos. A leírás célja, hogy segítsen az alapvető buktatók elkerülésében, valamint választ adjon az évről-évre a listán újra és újra elhangzó kérdésekre. | ||
| 11. sor: | 11. sor: | ||
__TOC__ | __TOC__ | ||
==Az | ==Az OpenGL és GLUT alapjai== | ||
=== Az OpenGL === | === Az OpenGL === | ||
* Az | * Az OpenGL egyszerű térbeli alakzatok (primtívek), pl.: pontok, vonalak, háromszögek rajzolására specializálódott. | ||
** Ezekből az építőkockákból csodákat lehet művelni, a mai számítógépes játékok nagyrészt hárszomszögek rajzolásából építkeznek. | ** Ezekből az építőkockákból csodákat lehet művelni, a mai számítógépes játékok nagyrészt hárszomszögek rajzolásából építkeznek. | ||
** A primitíveket nagyon sok féle képpen és nagyon hatékonyan lehet az | ** A primitíveket nagyon sok féle képpen és nagyon hatékonyan lehet az OpenGL-lel kirajzolni, de ezen kívül semmi mást nem tud, nem tud képet betölteni, árnyékokat számolni, de még egy kocka kirajzolásához is "küzdeni" kell. | ||
** Egy rajzolófüggvény viselkedése több száz paramétertől függ, persze nem kell az összeset függvény argumentumként átadni, ehelyett az '''OpenGL egy állapotgép'''-en alapszik. | ** Egy rajzolófüggvény viselkedése több száz paramétertől függ, persze nem kell az összeset függvény argumentumként átadni, ehelyett az '''OpenGL egy állapotgép'''-en alapszik. | ||
*** Ha valamit átállítasz (pl. a rajzolószínt), akkor az onnantól kezdve minden rajzolás-hívást befolyásol. | *** Ha valamit átállítasz (pl. a rajzolószínt), akkor az onnantól kezdve minden rajzolás-hívást befolyásol. | ||
* A legtöbb OpenGL függvényt több különböző típusú paraméterrel is meg lehet hívni, viszont az OpenGL egy C könyvtár, amiben nincs függvény overload. Ennek kiküszöbélésére a függvények neve Hungarian Notation szerűen a név végén tartalmaz pár karaktert, ami a paraméterekre utal, pl.: 3f - 3 db float, 2iv - 2 elemű int vector (azaz pointer egy 2 elemű int tömbre / 2db intet tartalmazó struktúrúra első tagjára / tetszőleges memóriaterületre, ahol 2 db int van egymás után) | * A legtöbb OpenGL függvényt több különböző típusú paraméterrel is meg lehet hívni, viszont az OpenGL egy C könyvtár, amiben nincs függvény overload. Ennek kiküszöbélésére a függvények neve Hungarian Notation szerűen a név végén tartalmaz pár karaktert, ami a paraméterekre utal, pl.: 3f - 3 db float, 2iv - 2 elemű int vector (azaz pointer egy 2 elemű int tömbre / 2db intet tartalmazó struktúrúra első tagjára / tetszőleges memóriaterületre, ahol 2 db int van egymás után) | ||
** pl.: glVertex3f() | ** pl.: glVertex3f() | ||
* Az | * Az OpenGL elnevezési konvenciója: | ||
** A függvények neve mindig kisbetűvel kezdődik, a gl, glu vagy glut szavakkal, attól függően hogy melyik függvénykönyvtárban található a függvény | ** A függvények neve mindig kisbetűvel kezdődik, a gl, glu vagy glut szavakkal, attól függően hogy melyik függvénykönyvtárban található a függvény | ||
** Ha több szóból áll, azokat egybeírjuk, és a szavakat nagy betűvel kezdjük (camelCase). | ** Ha több szóból áll, azokat egybeírjuk, és a szavakat nagy betűvel kezdjük (camelCase). | ||
*** pl.: glDrawElementsInstancedBaseVertexBaseInstance() - amúgy ez a leghosszabb nevű | *** pl.: glDrawElementsInstancedBaseVertexBaseInstance() - amúgy ez a leghosszabb nevű OpenGL függvény, de a tárgyból nincs rá szükség. | ||
* Az OpenGL RGB színskálán állítja elő a képet, és neki is RGB érétéket kell adni, ha egy színt akarunk leírni. A grafikában jobban szeretünk a (-végtelen, végtelen) tartományon dolgozni a színekkel, ezért általában nem a megszokott egy byte-on (0,255) specifikáljuk a színeket, hanem inkább floatként kezeljük őket a (0, 1) - vagy a (-1, 1) - tartományon. Ennek az az oka, hogy így jóval nagyobb fényerősség beli különbségek is megjeleníthetőek, két teljesen fehér fény összegeként kaphatunk egy fényesebb fehéret, amit csak a rajzolási fázis legvégén konvertálunk vissza a (0, 255) tartományra. Technikailag byte-ot is lehet adni az OpenGL-nek, de pedagógia okokból a házikban kötelező float színeket használni. | * Az OpenGL RGB színskálán állítja elő a képet, és neki is RGB érétéket kell adni, ha egy színt akarunk leírni. A grafikában jobban szeretünk a (-végtelen, végtelen) tartományon dolgozni a színekkel, ezért általában nem a megszokott egy byte-on (0,255) specifikáljuk a színeket, hanem inkább floatként kezeljük őket a (0, 1) - vagy a (-1, 1) - tartományon. Ennek az az oka, hogy így jóval nagyobb fényerősség beli különbségek is megjeleníthetőek, két teljesen fehér fény összegeként kaphatunk egy fényesebb fehéret, amit csak a rajzolási fázis legvégén konvertálunk vissza a (0, 255) tartományra. Technikailag byte-ot is lehet adni az OpenGL-nek, de pedagógia okokból a házikban kötelező float színeket használni. | ||
* Az | * Az OpenGL csak a rajzolással foglalkozik, az, hogy hogyan jön létre az a valami (célszerűen egy ablak), amire ő tud rajzolni, az viszont már nem az ő dolga. Itt jön a képbe a GLUT. | ||
=== A GLUT === | === A GLUT === | ||
| 40. sor: | 40. sor: | ||
* Az alapértelmezett koordináta-rendszer X, Y (és Z) koordinátái -1 és +1 között mozognak. 2D-ben (-1,-1) a bal alsó, (+1,+1) a jobb felső sarok. Ezeket ha nem muszáj, ne bolygassuk! | * Az alapértelmezett koordináta-rendszer X, Y (és Z) koordinátái -1 és +1 között mozognak. 2D-ben (-1,-1) a bal alsó, (+1,+1) a jobb felső sarok. Ezeket ha nem muszáj, ne bolygassuk! | ||
* Ha mégis módosítani kell, ez 2D-ben a gluOrtho2D(), 3D-ben a glFrustum() függvényekkel lehetséges. | * Ha mégis módosítani kell, ez 2D-ben a gluOrtho2D(), 3D-ben a glFrustum() függvényekkel lehetséges. | ||
* Az | * Az OpenGL 3D-s koordináta-rendszere jobb-sodrású, azaz ha az Y-tengely felfelé, míg az X-tengely jobbra mutat, akkor a Z-tengely felénk mutat kifelé a képernyőből | ||
* Az alapértelmezett projekció a 2D-s orthogonális vetítés, 2D-s rajzoláshoz tökéletesen megfelel. 3D-ben általában perspektivikus vetítést használunk, ezt a gluPerspective() függvénnyel állíthatjuk be. Ennek paraméterezése nem triviális, erről bővebben a 3D-ről szóló részben olvashatsz. | * Az alapértelmezett projekció a 2D-s orthogonális vetítés, 2D-s rajzoláshoz tökéletesen megfelel. 3D-ben általában perspektivikus vetítést használunk, ezt a gluPerspective() függvénnyel állíthatjuk be. Ennek paraméterezése nem triviális, erről bővebben a 3D-ről szóló részben olvashatsz. | ||
* Minden projekció módosító függvény valójában az | * Minden projekció módosító függvény valójában az OpenGL projekciós mátrixait állítja át. Erről bővebben a projekcióról szóló részben olvashatsz. Elöljáróban annyit, hogy ezeket a függvényeket csak egyszer hívd meg (pl.: onInitialization-ben), mert többszöri meghívásuk hatása összeadódik! | ||
==2D rajzolás== | ==2D rajzolás== | ||
| 190. sor: | 190. sor: | ||
===OpenGL rész=== | ===OpenGL rész=== | ||
* Sugárkövetésnél | * 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> | ||
glRasterPos2d(-1,-1); | glRasterPos2d(-1,-1); | ||
| 196. sor: | 196. sor: | ||
</pre> | </pre> | ||
* A | * A RasterPos segítségével a pixelenkénti rajzolás kezdő helyét adjuk meg, (-1,-1) a bal alsó sarok. | ||
* A | * A DrawPixels hívásal egy 600*600-as képet rajzolunk pixelenként a rasztertárba. A képet a picture tömb tárolja, melynek minden eleme RGB adatokat tárol float típussal. Az egész sugárkövetés célja, hogy ezt a szín-táblázatot feltöltsük az oda érkező fény színével és intenzitásával. | ||
* Egy ilyen tömböt a következő módon definiálhatunk: ''Color picture[600][600];'' ahol Color egy 3 float értéket tartalmazó osztály. A színkomponensek természetesen itt is 0-1 skálán értendők. | * Egy ilyen tömböt a következő módon definiálhatunk: ''Color picture[600][600];'' ahol Color egy 3 float értéket tartalmazó osztály. A színkomponensek természetesen itt is 0-1 skálán értendők. | ||
* 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. | ||