„Számítógépes grafika házi feladat tutorial” változatai közötti eltérés
Hozzáadtam a mátrix stack részt |
|||
| 3. sor: | 3. sor: | ||
{{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 | Ez a tutorial alapvetően azt hivatott elmagyarázni, hogy hogyan kell az OpenGL-t használni. Ebből adódóan még minimális kitérőt se tesz a házik mögött álló elméleti háttér kifejesére, csak abba ad segítséget, hogy hogyan oldd meg a házidat. A háziknak pont az a célja, hogy az órán elsajátított elméletet gyakorolni tudd, így ha az elémlet ismerete nélkül vágsz neki a házinak, az lehet, hogy sikerülni fog, de a tárgy szempontjából semmi értelme nem lesz... Ez a tutorial nem helyettesíti az órán való jelenlétet. | ||
'''Az oldalról kódot a saját házidba átemelni TILOS! Még ha pár sornyi kódról is van szó, gépeld be szépen magadtól, addig is gyakorlod a dolgot. Meg persze nem is érdemes másolgatni, mert csak borzolod vele a plágiumkereső idegeit, és sokban ronthat az esélyeiden az aláírás megszerzésére''' | '''Az oldalról kódot a saját házidba átemelni TILOS! Még ha pár sornyi kódról is van szó, gépeld be szépen magadtól, addig is gyakorlod a dolgot. Meg persze nem is érdemes másolgatni, mert csak borzolod vele a plágiumkereső idegeit, és sokban ronthat az esélyeiden az aláírás megszerzésére''' | ||
| 336. sor: | 336. sor: | ||
</div> | </div> | ||
- Egyáltalán nem intuitív, az origó a (7.817, 3.185) pontba kerül, és a két tengely nagyítása 2.084 és 2.43. Ezeknek az értékeknek semmi köze a kódban szereplő konstansokhoz!! <br/> <br/> | - Egyáltalán nem intuitív, az origó a (7.817, 3.185) pontba kerül, és a két tengely nagyítása 2.084 és 2.43. Ezeknek az értékeknek semmi köze a kódban szereplő konstansokhoz!! <br/> <br/> | ||
* Tanulság: általában az eltolás - forgatás - nagyítás sorrendet szeretjük. Ez nem jelenti azt, hogy más sorrendnek ne lenne értelme, vagy egy konkrét problémának ne lehetne egyszerűbb megoldása másmilyen sorrendet használva. | |||
* A probléma ami felmerül, hogy a transzformációk hatása permanens, azaz, ha egyszer elforgattad a világot, akkor az úgy marad, amíg vissza nem forgatod. Tehát ha egy objektum kirajzolása miatt akarsz hasznáni egy transzformációt akkor a rajzolás után azt mindenképpen, mindig vissza is kell csinálnod. De mi van ha egy összetett objektum kirajzolásához akár több száz transzformáció is kellet? Akkor a végén az összeset egybe vissza kell csinálni? Nincs erre jobb megoldás? A válasz természetesen az, hogy van, ez a megoldás a matrix stack. | |||
=== Matrix stack === | |||
* Az OpenGL két függvényt ad amivel a matrix stack-et használhatjuk: | |||
** <code> glPushMatrix(); </code> | |||
*** A jelenleg aktív mátrixot (<code> GL_PROJECTION </code> vagy <code> GL_MODELVIEW </code> ) elmenti annak a stackjébe. | |||
** <code> glPopMatrix(); </code> | |||
*** A jelenleg aktív mátrix stackjéből a legutóbb elmentett mátrixot visszaáálítja. A következő glPopMatrix() mátrix az az előtt elentett mátrixot állítja vissza. | |||
* Megjegyzések: | |||
** A <code> GL_MODELVIEW </code> stack mélysége legalább 32, a GL_PROJECTION mátrix-é pedig legalább 2. | |||
*** Ez azt jelenti, hogy lehet, hogy nálad mindkét érték tízszer ekkora, de ha hordozható kódot akarsz írni, ekkor ennél nagyobb számokat nem feltételezhetsz. | |||
*** Overflow / Underflow esetén a mátrix értéke meghatározatlan lesz. | |||
* Pl: | |||
<br/> <syntaxhighlight lang="c"> | |||
glMatrixMode(GL_MODELVIEW); | |||
glLoadIdentity(); | |||
glPushMatrix(); { | |||
glRotatef(90, 0, 0, 1); | |||
rajzolas(); // A rajzolaskor a világ el van forgatva | |||
} glPopMatrix(); | |||
rajzolas2(); // It a világ már nincs elforgatva. | |||
</syntaxhighlight> <br/> | |||
* A matrix stack hierarchikusan felépülő testek rajzolását nagy mértékben megkönnyíti. | |||
** Hierarhikus test pl: az emberi kéz. | |||
*** Ha a felkarod elforgatod a vállad körül, akkor azzal az alkarod a csuklód és az ujjaid elmozdulnak. Minden izület transzformációja befolyásolja az összes csontot, ami belőle nő ki, és az összes csontot, ami a belőle kinövő csontokból nő ki, rekurzívan. Ha ezt manuálisan akarnánk leprogramozni, egy olyan fát kéne felépítenünk az izületekből, ahol a gyerekek száma változó. Ez nem lehetelen, de is kifejezetten izgalmas, viszont a matrix stack segítségével ez nagyon egyszerűen megoldhaó. | |||
*** Pszeudó kóddal, feltételezve, hogy origó középpontú, egység hosszú, x-el párhuzamos főtengelyű hengert tudunk rajzolni a "henger kirajzolása" utasítással: | |||
<pre> | |||
glPushMatrix(); { | |||
váll körüli forgatás | |||
felkar hosszának a felével eltolás az x tengely mentén | |||
glPushMatrix(); { | |||
nagyítás a felkar méreteivel | |||
henger kirajzolása | |||
} glPopMatrix(); | |||
felkar hosszának a felével eltolás az x tengely mentén | |||
könyök körüli forgatás | |||
alkar hosszának a felével eltolás az x tengely mentén | |||
glPushMatrix(); { | |||
nagyítás a alkar méreteivel | |||
henger kirajzolása | |||
} glPopMatrix(); | |||
alkar hosszának a felével eltolás az x tengely mentén | |||
kéz kirajzolása | |||
} glPopMatrix(); | |||
</pre> | |||
* Sajnos ezt 2D-be nem lehet jól megmutatni, ezért kivételesen az ehhez kapcsolódó példaprogram 3D-s lesz. | |||
** Technikailag a 3D rajzolást rábízzuk a glut-ra. | |||
*** Kizárólag a <code> glutSolidCube() </code> függvényt fogjuk használni. | |||
*** Ez a függvény - nem meglepő módón - egy [http://pastebin.com/HJKcgBsA kockát rajzol ki]: | |||
<div style="text-align:left;margin:0px auto;"> | |||
http://i.imgur.com/PA2A3eQ.png | |||
</div><br/> | |||
* Ezt felhasználva a példaprogram: [http://pastebin.com/a3XtuCVh Robot kar] | |||
** A program irányítása: | |||
*** 'q' - Ujjak szétnyitása, 'a' - Ujjak összezárása | |||
*** 'w' - Alkar felemelése, 's' - Alkar lehajtása | |||
*** 'e' - Felkar felemelése, 'd' - Felkar lehajtása | |||
*** 'r' - Az alap forgatása jobbra, 'f' - Az alap forgatása balra | |||
<br/> <syntaxhighlight lang="c"> | |||
struct Vector { | |||
float x, y, z; | |||
Vector(float x, float y, float z) : x(x), y(y), z(z) { } | |||
void glTranslatef() { ::glTranslatef(x, y, z); } | |||
void glRotatef(float angle) { ::glRotatef(angle, x, y, z); } | |||
void glScalef() { ::glScalef(x, y, z); } | |||
}; | |||
Vector x_axis(1, 0, 0), y_axis(0, 1, 0), z_axis(0, 0, 1); | |||
Vector pos_crate(0, 0, -5), pos_left_base(1, 0, 0), pos_right_base(-1, 0, 0), scale_base(1, 1, 3), | |||
pos_main_arm(0, 0, -2), scale_main_arm(1, 1, 4), pos_lower_arm(0, 0, -1.5f), | |||
scale_lower_arm(0.7f, 0.7f, 3.0f), scale_wrist(1, 1, 1), pos_left_finger(0.5f, -1.0f, 0.0f), | |||
pos_right_finger(-0.5f, -1.0f, 0.0f), scale_finger(0.2f, 1.0f, 0.2f); | |||
float rot_base = 0, rot_main_arm = 70, rot_lower_arm = -60, | |||
rot_finger = 20, rot_finger_relative = 20; | |||
void onDisplay() { | |||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||
glPushMatrix(); { | |||
y_axis.glRotatef(rot_base); | |||
// Jobb oldali alap | |||
glPushMatrix(); { | |||
pos_right_base.glTranslatef(); | |||
scale_base.glScalef(); | |||
glutSolidCube(1.0f); | |||
} glPopMatrix(); | |||
// Bal oldali alap | |||
glPushMatrix(); { | |||
pos_left_base.glTranslatef(); | |||
scale_base.glScalef(); | |||
glutSolidCube(1.0f); | |||
} glPopMatrix(); | |||
x_axis.glRotatef(rot_main_arm); | |||
pos_main_arm.glTranslatef(); | |||
// Felkar | |||
glPushMatrix(); { | |||
scale_main_arm.glScalef(); | |||
glutSolidCube(1.0f); | |||
} glPopMatrix(); | |||
pos_main_arm.glTranslatef(); | |||
x_axis.glRotatef(rot_lower_arm); | |||
pos_lower_arm.glTranslatef(); | |||
// Alkar | |||
glPushMatrix(); { | |||
scale_lower_arm.glScalef(); | |||
glutSolidCube(1.0f); | |||
} glPopMatrix(); | |||
pos_lower_arm.glTranslatef(); | |||
// Csukló | |||
glPushMatrix(); { | |||
scale_wrist.glScalef(); | |||
glutSolidCube(1.0f); | |||
} glPopMatrix(); | |||
// Jobb 'ujj' | |||
glPushMatrix(); { | |||
z_axis.glRotatef(-rot_finger); | |||
glTranslatef(0, pos_right_finger.y, 0); | |||
glPushMatrix(); { | |||
glTranslatef(pos_right_finger.x, 0, 0); | |||
z_axis.glRotatef(-rot_finger_relative); | |||
scale_finger.glScalef(); | |||
glutSolidCube(1.0f); | |||
} glPopMatrix(); | |||
pos_right_finger.glTranslatef(); | |||
z_axis.glRotatef(rot_finger_relative); | |||
scale_finger.glScalef(); | |||
glutSolidCube(1.0f); | |||
} glPopMatrix(); | |||
// Bal 'ujj' | |||
glPushMatrix(); { | |||
z_axis.glRotatef(rot_finger); | |||
glTranslatef(0, pos_left_finger.y, 0); | |||
glPushMatrix(); { | |||
glTranslatef(pos_left_finger.x, 0, 0); | |||
z_axis.glRotatef(rot_finger_relative); | |||
scale_finger.glScalef(); | |||
glutSolidCube(1.0f); | |||
} glPopMatrix(); | |||
pos_left_finger.glTranslatef(); | |||
z_axis.glRotatef(-rot_finger_relative); | |||
scale_finger.glScalef(); | |||
glutSolidCube(1.0f); | |||
} glPopMatrix(); | |||
} glPopMatrix(); | |||
// Láda | |||
glPushMatrix(); { | |||
pos_crate.glTranslatef(); | |||
glutSolidCube(1.0f); | |||
} glPopMatrix(); | |||
glutSwapBuffers(); | |||
} | |||
</syntaxhighlight> <br/> | |||
Az eredménye: | |||
<div style="text-align:left;margin:0px auto;"> | |||
http://i.imgur.com/tpAuxBa.gif | |||
</div> | |||
== Régi wikiről áthozott rész, frissitésre szorul == | == Régi wikiről áthozott rész, frissitésre szorul == | ||