This shows you the differences between two versions of the page.
egc:laboratoare:02 [2019/10/06 12:11] andrei.lambru |
egc:laboratoare:02 [2023/10/18 19:11] (current) mihnea.mitrache [Face Culling] |
||
---|---|---|---|
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** |