This shows you the differences between two versions of the page.
|
egc:laboratoare:02 [2019/10/06 12:11] andrei.lambru |
egc:laboratoare:02 [2025/11/26 20:37] (current) andrei.voicu2409 [Cerințe laborator] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Laboratorul 02 ====== | ====== Laboratorul 02 ====== | ||
| + | |||
| + | **Video Laborator 2**: https://youtu.be/RtXuIQO8l0U.\\ | ||
| + | **Autor**: [[alex.gradinaru@cs.pub.ro | Alex Gradinaru]] | ||
| ===== OpenGL – Date ===== | ===== OpenGL – Date ===== | ||
| Line 10: | Line 13: | ||
| **Shaderele** vor fi introduse pe parcursul cursului. \\ | **Shaderele** vor fi introduse pe parcursul cursului. \\ | ||
| - | **Stările** reprezintă un concept mai larg, OpenGL fiind de fapt un mare automat finit cu o mulțime de stări și posibilități de a trece dintr-o stare în alta. De-a lungul laboratoarelor o parte din aceste stări vor fi folosite pentru a obține efectele dorite.\\ | + | **Stările** reprezintă un concept mai larg, OpenGL fiind de fapt un mare automat finit cu o mulțime de stări și posibilități de a seta aceste stări. De-a lungul laboratoarelor o parte din aceste stări vor fi folosite pentru a obține efectele dorite.\\ |
| **Datele** conțin informațiile ce definesc scena, precum: | **Datele** conțin informațiile ce definesc scena, precum: | ||
| * obiecte tridimensionale | * obiecte tridimensionale | ||
| Line 48: | Line 51: | ||
| <note important> | <note important> | ||
| - | În cadrul framework-ului puteți seta tipul de primitivă utilizat de către un obiect la randare prin intermediul funcției [[https://github.com/UPB-Graphics/Framework-EGC/blob/master/Source/Core/GPU/Mesh.h#L99|Mesh::SetDrawMode(GLenum primitive)]] unde ''primitive'' poate fi oricare dintre primitivele menționate în imaginea de mai sus. | + | În cadrul framework-ului puteți seta tipul de primitivă utilizat de către un obiect la randare prin intermediul funcției [[https://github.com/UPB-Graphics/gfx-framework/blob/master/src/core/gpu/mesh.h#L84|Mesh::SetDrawMode(GLenum primitive)]] unde ''primitive'' poate fi oricare dintre primitivele menționate în imaginea de mai sus. |
| </note> | </note> | ||
| ==== Ordinea specificării vârfurilor ==== | ==== Ordinea specificării vârfurilor ==== | ||
| Line 58: | Line 61: | ||
| ==== Face Culling ==== | ==== Face Culling ==== | ||
| - | API-ul OpenGL oferă posibilitatea de a testa orientarea aperentă pe ecran a fiecărui triunghi înainte ca acesta să fie redat și să îl ignore în funcție de starea de discard setată: **GL_FRONT** sau **GL_BACK**. Acestă funcționalitate poartă numele de **[[https://www.opengl.org/wiki/Face_Culling|Face Culling]]** și este foarte importantă deoarece reduce costul de procesare total. | + | API-ul OpenGL oferă posibilitatea de a testa orientarea aparentă pe ecran a fiecărui triunghi înainte ca acesta să fie redat și să îl ignore în funcție de starea de discard setată: **GL_FRONT** sau **GL_BACK**. Acestă funcționalitate poartă numele de **[[https://www.opengl.org/wiki/Face_Culling|Face Culling]]** și este foarte importantă deoarece reduce costul de procesare total. |
| + | |||
| + | Modul cum este considerată o față ca fiind **GL_FRONT** sau **GL_BACK** poate fi schimbat folosind comanda [[https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glFrontFace.xhtml|glFrontFace]] (valoarea inițială pentru o față **GL_FRONT** este considerată ca având ordinea specificării vârfurilor în sens trigonometric / counter clockwise): | ||
| + | <code cpp> | ||
| + | // mode can be GL_CW (clockwise) or GL_CCW (counterclockwise) | ||
| + | // the initial value is GL_CCW | ||
| + | void glFrontFace(GLenum mode); | ||
| + | </code> | ||
| <note> | <note> | ||
| Line 80: | Line 90: | ||
| glCullFace(GL_BACK); | glCullFace(GL_BACK); | ||
| </code> | </code> | ||
| + | |||
| + | <note> În concluzie, atunci când ne propunem să definim geometria unui | ||
| + | obiect este foarte importantă ordinea specificării indicilor. | ||
| + | </note> | ||
| + | |||
| + | <note tip> Pentru o definire corectă se pot urma pașii: | ||
| + | - Ne fixăm privirea pe o anumită axa. | ||
| + | - Identificăm fețele vizibile și cele nevizibile. | ||
| + | - Triunghiurile care alcătuiesc fețele vizibile se specifică în ordine trigonometrică iar cele nevizibile în ordinea inversă. | ||
| + | </note> | ||
| + | |||
| + | {{ :egc:laboratoare:lab02:cull_face.png?750 |}} | ||
| + | |||
| + | <note warning>Dacă vă întrebați de ce după ce ați activat CULL_FACE obiectele voastre nu arată | ||
| + | corect, cel mai probabil ați fost inconsecvenți în ceea ce privește ordinea de specificare a | ||
| + | indicilor. | ||
| + | </note> | ||
| ===== Meshe ===== | ===== Meshe ===== | ||
| - | Un „mesh” este un obiect tridimensional definit prin vârfuri și indici. În laborator aveți posibilitatea să încărcați meshe în aproape orice format posibil prin intermediul clasei [[https://github.com/UPB-Graphics/Framework-EGC/blob/master/Source/Core/GPU/Mesh.h#L67|Mesh]]. | + | Un „mesh” este un obiect tridimensional definit prin vârfuri și indici. În laborator aveți posibilitatea să încărcați meshe în aproape orice format posibil prin intermediul clasei [[https://github.com/UPB-Graphics/gfx-framework/blob/master/src/core/gpu/mesh.h#L48|Mesh]]. |
| Line 128: | Line 155: | ||
| <note tip> | <note tip> | ||
| - | Pentru a înțelege mai bine API-ul OpenGL vă rocomandăm să citiți documentația indicată pentru fiecare comandă prezentată. Atunci când se prezintă o nouă comandă, dacă apăsați click pe numele acesteia veți fi redirecționați către pagina de manual a comenzii respective.\\ | + | Pentru a înțelege mai bine API-ul OpenGL vă recomandăm să citiți documentația indicată pentru fiecare comandă prezentată. Atunci când se prezintă o nouă comandă, dacă apăsați click pe numele acesteia veți fi redirecționați către pagina de manual a comenzii respective.\\ |
| De asemenea, documentația oficială și completă a API-ului OpenGL poate fi gasită pe pagina **[[https://www.opengl.org/sdk/docs/man/|OpenGL 4 Reference Pages]]** | De asemenea, documentația oficială și completă a API-ului OpenGL poate fi gasită pe pagina **[[https://www.opengl.org/sdk/docs/man/|OpenGL 4 Reference Pages]]** | ||
| </note> | </note> | ||
| Line 175: | Line 202: | ||
| În cadrul laboratorului vom învăța să folosim **VAO, VBO, IBO** și astfel să generăm și încărcăm geometrie simplă.\\ | În cadrul laboratorului vom învăța să folosim **VAO, VBO, IBO** și astfel să generăm și încărcăm geometrie simplă.\\ | ||
| - | Laboratorul pune la dispoziție structura [[https://github.com/UPB-Graphics/Framework-EGC/blob/master/Source/Core/GPU/Mesh.h#L14|VertexFormat]] ce va fi utilizată ca bază pentru a crea geometria. | + | Laboratorul pune la dispoziție structura [[https://github.com/UPB-Graphics/gfx-framework/blob/master/src/core/gpu/vertex_format.h|VertexFormat]] ce va fi utilizată ca bază pentru a crea geometria. |
| <code cpp> | <code cpp> | ||
| Line 199: | Line 226: | ||
| // Initializes the mesh object using a VAO GPU buffer that contains the specified number of indices | // Initializes the mesh object using a VAO GPU buffer that contains the specified number of indices | ||
| - | bool InitFromBuffer(unsigned int VAO, unsigned short nrIndices); | + | bool InitFromBuffer(unsigned int VAO, unsigned int nrIndices); |
| // Initializes the mesh object and upload data to GPU using the provided data buffers | // Initializes the mesh object and upload data to GPU using the provided data buffers | ||
| - | bool InitFromData(std::vector<VertexFormat> vertices, | + | bool InitFromData(const std::vector<VertexFormat>& vertices, |
| - | std::vector<unsigned short>& indices); | + | const std::vector<unsigned int>& indices); |
| // Initializes the mesh object and upload data to GPU using the provided data buffers | // Initializes the mesh object and upload data to GPU using the provided data buffers | ||
| - | bool InitFromData(std::vector<glm::vec3>& positions, | + | bool InitFromData(const std::vector<glm::vec3>& positions, |
| - | std::vector<glm::vec3>& normals, | + | const std::vector<glm::vec3>& normals, |
| - | std::vector<unsigned short>& indices); | + | const std::vector<unsigned int>& indices); |
| </code> | </code> | ||
| <note tip> | <note tip> | ||
| Line 223: | Line 250: | ||
| <note important> | <note important> | ||
| - | Toate cerințele ce țin de încărcare de geometrie trebuie rezolvate prin intermediul funcției ''Laborator2::CreateMesh'' dar puteți folosi metodele ''Mesh::InitFromData()'' pentru a verifica validitatea geometriei. | + | Toate cerințele ce țin de încărcare de geometrie trebuie rezolvate prin intermediul funcției ''Lab2::CreateMesh'' dar puteți folosi metodele ''Mesh::InitFromData()'' pentru a verifica validitatea geometriei. |
| </note> | </note> | ||
| - | - Descărcați [[https://github.com/UPB-Graphics/Framework-EGC/archive/master.zip|framework-ul de laborator]] | + | - Descărcați [[https://github.com/UPB-Graphics/gfx-framework/archive/master.zip|framework-ul de laborator]] |
| - Completați geometria și topologia unui cub: vectorii de vertecși și indecși din inițializare. ''VertexFormat'' este o structură pentru vertex cu 2 parametrii (poziție, culoare). | - Completați geometria și topologia unui cub: vectorii de vertecși și indecși din inițializare. ''VertexFormat'' este o structură pentru vertex cu 2 parametrii (poziție, culoare). | ||
| - | - Completați funcția ''Laborator2::CreateMesh'' astfel încât să încărcați geometria pe GPU | + | - Completați funcția ''Lab2::CreateMesh'' astfel încât să încărcați geometria pe GPU |
| * creați un VAO | * creați un VAO | ||
| * creați un VBO și adăugați date în el | * creați un VBO și adăugați date în el | ||
| * creați un IBO și adăugați date în el | * creați un IBO și adăugați date în el | ||
| - | * afișați noul obiect (RenderMesh[cube3]) astfel încât să nu se suprapună cu un alt obiect | + | * afișați noul obiect (RenderMesh[cube_B]) astfel încât să nu se suprapună cu un alt obiect |
| - Creați o nouă formă geometrică simplă, de exemplu un tetraedru și desenați-l în scenă | - Creați o nouă formă geometrică simplă, de exemplu un tetraedru și desenați-l în scenă | ||
| - Atunci când se apasă tasta **F2** faceți toggle între modul de culling **GL_BACK** și **GL_FRONT** | - Atunci când se apasă tasta **F2** faceți toggle între modul de culling **GL_BACK** și **GL_FRONT** | ||
| Line 250: | Line 277: | ||
| - **[Bonus]** Creați un obiect mai complex, format din cel puțin 4 fețe (tetraedru) astfel încât fiecare față să fie desenată cu câte o singură culoare. | - **[Bonus]** Creați un obiect mai complex, format din cel puțin 4 fețe (tetraedru) astfel încât fiecare față să fie desenată cu câte o singură culoare. | ||
| * explicați studenților de ce e nevoie să declare fiecare vertex de 3 ori cu culori diferite (în cazul tetraedrului) | * explicați studenților de ce e nevoie să declare fiecare vertex de 3 ori cu culori diferite (în cazul tetraedrului) | ||
| + | - **[Bonus]** Realizarea unui torus generat procedural, utilizând parametrizarea în două unghiuri și discretizarea acestora pentru a construi geometria (vertecși și indici). Un torus poate fi descris prin ecuația parametrică p(u,v)=((R+rcosv)cosu, (R+rcosv)sinu, rsinv) | ||
| </hidden> | </hidden> | ||