Differences

This shows you the differences between two versions of the page.

Link to this comparison view

egc:laboratoare:02 [2019/10/06 11:51]
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 =====
  
-Daca am încerca să reducem întregul API de OpenGL la mari concepte acestea ar fi:+Dacă am încerca să reducem întregul API de OpenGL la mari concepte acestea ar fi:
   * date   * date
   * stări   * stări
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
     * proprietăți de material ale obiectelor (plastic, sticlă, etc)     * proprietăți de material ale obiectelor (plastic, sticlă, etc)
-    * pozițiile, orientările și dimensiunile obiectelor ​lor în scenă+    * pozițiile, orientările și dimensiunile obiectelor în scenă
     * orice alte informații necesare ce descriu proprietăți de obiecte sau de scenă     * orice alte informații necesare ce descriu proprietăți de obiecte sau de scenă
  
Line 21: Line 24:
   * caracteristicile vârfurilor   * caracteristicile vârfurilor
     * dacă singura caracteristică a unui vârf în afară de poziție ar fi culoarea am avea încă 4 vectori tridimensionali (RGB)     * dacă singura caracteristică a unui vârf în afară de poziție ar fi culoarea am avea încă 4 vectori tridimensionali (RGB)
-  * topologia pătratului,​ adică ​metoda prin care legăm aceste vârfuri+  * topologia pătratului,​ adică ​modul în care legăm aceste vârfuri
 </​note>​ </​note>​
  
Line 41: Line 44:
 {{ :​egc:​laboratoare:​lab02:​gl_geometric_primitives.png?​nolink |}} {{ :​egc:​laboratoare:​lab02:​gl_geometric_primitives.png?​nolink |}}
  
-Dupa cum se poate observa, există mai multe metode prin care geometria poate fi specificată:​+După cum se poate observa, există mai multe metode prin care geometria poate fi specificată:​
   * **GL_LINES** și **GL_TRIANGLES** sunt cele mai des utilizate primitive pentru definirea geometriei   * **GL_LINES** și **GL_TRIANGLES** sunt cele mai des utilizate primitive pentru definirea geometriei
   * **GL_POINTS** este des utilizat pentru a crea sistemele de particule   * **GL_POINTS** este des utilizat pentru a crea sistemele de particule
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 91: Line 118:
   * poziție   * poziție
   * normală   * normală
-  * culoarea+  * culoare
   * coordonate de texturare   * coordonate de texturare
   * etc...   * etc...
Line 111: Line 138:
 </​code>​ </​code>​
  
-Pentru a putea pune date într-un buffer trebuie întâi să legăm acest buffer la un „target”. Pentru un vertex buffer acest „binding point” se numește **GL_ARRAY_BUFFER**și se poate specifica prin comanda **[[https://​www.khronos.org/​opengles/​sdk/​1.1/​docs/​man/​glBindBuffer.xml|glBindBuffer]]**:​+Pentru a putea pune date într-un buffer trebuie întâi să legăm acest buffer la un „target”. Pentru un vertex buffer acest „binding point” se numește **GL_ARRAY_BUFFER** și se poate specifica prin comanda **[[https://​www.khronos.org/​opengles/​sdk/​1.1/​docs/​man/​glBindBuffer.xml|glBindBuffer]]**:​
  
 <code cpp> <code cpp>
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 134: Line 161:
 ==== Index Buffer Object (IBO) ==== ==== Index Buffer Object (IBO) ====
  
-Un index buffer object (numit și element buffer object) reprezintă un container în care stocăm indicii vertecșilor. Cum **VBO** si **IBO** sunt buffere, ele sunt extrem de similare ​in constructieincarcare ​de date si destructie.+Un index buffer object (numit și element buffer object) reprezintă un container în care stocăm indicii vertecșilor. Cum **VBO** si **IBO** sunt buffere, ele sunt extrem de similare ​în construcțieîncărcare ​de date și ștergere.
  
 <code cpp> <code cpp>
Line 168: Line 195:
 </​note>​ </​note>​
  
-Înainte de comanda de desenare este suficient să legăm doar VAO-ul ca OpenGL ​sa știe toate legatările create la construcția obiectului.+Înainte de comanda de desenare este suficient să legăm doar VAO-ul ca OpenGL ​să știe toate legatările create la construcția obiectului.
  
 ===== Laborator 2 ===== ===== Laborator 2 =====
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 215: Line 242:
   * **MOUSE RIGHT + MOUSE MOVE** - rotație cameră   * **MOUSE RIGHT + MOUSE MOVE** - rotație cameră
  
-**F3** - afișează/​ascunde gridul din scena \\ +**F3** - afișează/​ascunde gridul din scenă ​\\ 
 **Space** - desenează primitivele doar prin **puncte** sau **linii** (wireframe) sau **geometrie opacă** **Space** - desenează primitivele doar prin **puncte** sau **linii** (wireframe) sau **geometrie opacă**
  
 </​note>​ </​note>​
  
-==== Cerinte ​laborator ====+==== Cerințe ​laborator ====
  
 <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]] 
-  - Completati ​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 245: Line 272:
   - **[Bonus]** Folosind ''​Mesh::​SetDrawMode()''​ să se genereze un obiect geometric specificat prin **GL_TRIANGLE_FAN** sau **GL_TRIANGLE_STRIP** sau **GL_LINE_LOOP**   - **[Bonus]** Folosind ''​Mesh::​SetDrawMode()''​ să se genereze un obiect geometric specificat prin **GL_TRIANGLE_FAN** sau **GL_TRIANGLE_STRIP** sau **GL_LINE_LOOP**
     * exemple: ​     * exemple: ​
-      * să se genereze programabil un cerc având un număr **N** de laturi+      * să se genereze programabil un disc de cerc având un număr **N** de laturi
       * să se creeze o interpolare discretă pentru funcția sin/cos în intervalul (0, 2PI) folosind **N** linii       * să se creeze o interpolare discretă pentru funcția sin/cos în intervalul (0, 2PI) folosind **N** linii
       * să se mărească/​micșoreze numărul **N** prin apăsarea unor taste       * să se mărească/​micșoreze numărul **N** prin apăsarea unor taste
egc/laboratoare/02.1570351893.txt.gz · Last modified: 2019/10/06 11:51 by andrei.lambru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0