„Számítógépes grafika házi feladat tutorial” változatai közötti eltérés

Rohamcsiga (vitalap | szerkesztései)
a Kiszedtem pár rossz linket
Rohamcsiga (vitalap | szerkesztései)
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#H.C3.A1zi}}
{{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 [[OpenGL]] és GLUT alapjai==
==Az OpenGL és GLUT alapjai==
=== Az OpenGL ===
=== Az OpenGL ===
* Az [[OpenGL]] egyszerű térbeli alakzatok (primtívek), pl.: pontok, vonalak, háromszögek rajzolására specializálódott.
* 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 [[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.  
** 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 [[OpenGL]] elnevezési konvenciója:
* 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ű [[OpenGL]] függvény, de a tárgyból nincs rá szükség.
*** 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 [[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.
* 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 [[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 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 [[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!
* 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 [[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>
glRasterPos2d(-1,-1);
glRasterPos2d(-1,-1);
196. sor: 196. sor:
</pre>
</pre>


* A [[RasterPos]] segítségével a pixelenkénti rajzolás kezdő helyét adjuk meg, (-1,-1) a bal alsó sarok.
* A RasterPos segítségével a pixelenkénti rajzolás kezdő helyét adjuk meg, (-1,-1) a bal alsó sarok.
* 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.
* 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.