This is an old revision of the document!
Video Laborator 4: https://youtu.be/huCrfe9sbMQ
Autor: Alex Dinu
Obiectele 3D sunt definite într-un sistem de coordonate 3D, de exemplu XYZ. În cadrul acestui laborator vom implementa diferite tipuri de transformări ce pot fi aplicate obiectelor: translații, rotații și scalări. Acestea sunt definite în format matriceal, în coordonate omgene, așa cum ați învățat deja la curs. Matricile acestor transformări sunt următoarele:
$$ \begin{bmatrix} {x}'\\ {y}'\\ {z}'\\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 & t_x\\ 0 & 1 & 0 & t_y\\ 0 & 0 & 1 & t_z\\ 0 & 0 & 0 &1 \end{bmatrix} \begin{bmatrix} x\\ y\\ z\\ 1 \end{bmatrix} $$
$$ \begin{bmatrix} {x}'\\ {y}'\\ {z}'\\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & cos(u) & -sin(u) & 0 \\ 0 & sin(u) & cos(u) & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x\\ y\\ z\\ 1 \end{bmatrix} $$
$$ \begin{bmatrix} {x}'\\ {y}'\\ {z}'\\ 1 \end{bmatrix} = \begin{bmatrix} cos(u) & 0 & sin(u) & 0\\ 0 & 1 & 0 & 0 \\ -sin(u) & 0 & cos(u) & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x\\ y\\ z\\ 1 \end{bmatrix} $$
$$ \begin{bmatrix} {x}'\\ {y}'\\ {z}'\\ 1 \end{bmatrix} = \begin{bmatrix} cos(u) & -sin(u) & 0 & 0\\ sin(u) & cos(u) & 0 & 0\\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x\\ y\\ z\\ 1 \end{bmatrix} $$
Rotația relativă la o axă paralelă cu axa OX se rezolvă în cel mai simplu mod prin:
Similar se procedeaza și pentru axele paralele cu OY și OZ.
La curs veți învăța cum puteți realiza rotații față de axe oarecare (care nu sunt paralele cu OX, OY sau OZ).
$$ \begin{bmatrix} {x}'\\ {y}'\\ {z}'\\ 1 \end{bmatrix} = \begin{bmatrix} s_x & 0 & 0 &0 \\ 0 & s_y & 0 &0 \\ 0 & 0 & s_z &0 \\ 0 & 0 & 0 &1 \end{bmatrix} \begin{bmatrix} x\\ y\\ z\\ 1 \end{bmatrix} $$
Dacă $sx = sy = sz$ atunci avem scalare uniformă, altfel avem scalare neuniformă.
Scalarea relativă la un punct oarecare se rezolvă în cel mai simplu mod prin:
În cadrul laboratorului folosim biblioteca GLM care este o bibliotecă implementată cu matrici în formă coloană, exact același format ca OpenGL. Forma coloană diferă de forma linie prin ordinea de stocare a elementelor matricei în memorie, Matricea de translație arată în modul următor în memorie:
glm::mat4 Translate(float tx, float ty, float tz) { return glm::mat4( 1, 0, 0, 0, // coloana 1 in memorie 0, 1, 0, 0, // coloana 2 in memorie 0, 0, 1, 0, // coloana 3 in memorie tx, ty, tz, 1); // coloana 4 in memorie }
Din această cauză, este convenabil ca matricile să fie scrise manual în forma aceasta:
glm::mat4 Translate(float tx, float ty, float tz) { return glm::transpose( glm::mat4( 1, 0, 0, tx, 0, 1, 0, ty, 0, 0, 1, tz, 0, 0, 0, 1) ); }
transform3D.h
sunt definite funcțiile pentru calculul matricilor de translație, rotație și scalare. În momentul acesta toate funcțiile întorc matricea identitate. În cadrul laboratorului va trebui să modificați codul pentru a calcula matricile respective.
lab4.cpp
, există o serie de obiecte (cuburi) pentru care, în funcția Update()
, inainte de desenare, se definesc matricile de transformări. Comanda de desenare se dă prin funcția RenderMesh()
, care are ca parametru și matricea de transformări.
modelMatrix = glm::mat4(1); modelMatrix *= Transform2D::Translate(1, 2, 1); RenderMesh(meshes["box"], modelMatrix);
Pentru exemplul anterior, matricea de translație creată va avea ca efect translatarea cubului curent cu (1, 2, 1). Pentru efecte de animație continuă, pașii de translație ar trebui să se modifice în timp.
în laboratorul 3, s-a discutat despre transformarea fereastră-poartă si a fost parcursă matematica din spatele ei. în realitate, transformarea fereastră-poartă face parte din transformările fixe din banda grafică și nu este o operație care poate fi modificată de programatorul care se folosește de OpenGL.
Modul în care se poate interacționa cu transformarea fereastră-poartă în OpenGL este funcția:
glViewport(GLint x, GLint y, GLint width, GLint height)
Această funcție specifică OpenGLului că ceea ce urmează să fie trimis către randare va trebui să apară pe ecran în coordonatele fizice: $$(x, y) – (x + width, y + height)$$
Depth Buffer: Depth bufferul (sau Z bufferul) este o structură în care se menține adâncimea în scenă a fiecărui fragment din imaginea desenată.
glViewport poate fi extrem de util în diverse situații în care s-ar dori redarea mai multor puncte de vedere dintr-o scenă în același timp, ca de exemplu: oglinzi retrovizoare într-un joc cu mașini sau o hartă văzută de sus care se actualizează odată cu mișcarea jucătorului, cum se poate observa în animația de mai jos:
/lab4/transform3D.h
OnInputUpdate
) pentru cele 3 cuburi, astfel: