This shows you the differences between two versions of the page.
egc:laboratoare:02 [2018/10/09 13:11] alexandru.gradinaru [Cerinte laborator] |
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 incerca sa reducem intregul 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 | ||
- | * stari | + | * stări |
* shadere | * shadere | ||
**Shaderele** vor fi introduse pe parcursul cursului. \\ | **Shaderele** vor fi introduse pe parcursul cursului. \\ | ||
- | **Starile** reprezinta un concept mai larg, OpenGL fiind de fapt un mare automat finit cu o multime de stari si posibilitati de a trece dintr-o stare in alta. De-a lungul laboratoarelor o parte din aceste stari 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** contin informatiile ce definesc scena, precum: | + | **Datele** conțin informațiile ce definesc scena, precum: |
* obiecte tridimensionale | * obiecte tridimensionale | ||
- | * proprietati de material ale obiectelor (plastic, sticla, etc) | + | * proprietăți de material ale obiectelor (plastic, sticlă, etc) |
- | * pozitiile, orientarile si dimensiunile obiectelor lor in scena | + | * pozițiile, orientările și dimensiunile obiectelor în scenă |
- | * orice alte informatii necesare ce descriu proprietati de obiecte sau de scena | + | * orice alte informații necesare ce descriu proprietăți de obiecte sau de scenă |
- | <note>De exemplu pentru o scena cu un singur patrat avem urmatoarele date: | + | <note>De exemplu pentru o scenă cu un singur pătrat avem următoarele date: |
- | * varfurile patratului - 4 vectori tridimensionali ce definesc pozitia fiecarui varf in spatiu | + | * vârfurile pătratului - 4 vectori tridimensionali ce definesc poziția fiecărui vârf în spațiu |
- | * caracteristicile varfurilor | + | * caracteristicile vârfurilor |
- | * daca singura caracteristica a unui varf in afara de pozitie ar fi culoarea am avea inca 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 patratului, adica metoda prin care legam aceste varfuri | + | * topologia pătratului, adică modul în care legăm aceste vârfuri |
</note> | </note> | ||
<note important> | <note important> | ||
- | OpenGL este este un API de grafica tridimensionala, adica, toate obiectele care pot fi definite sunt raportate la un sistem de coordonate carteziene tridimensional. Cu toate acestea putem utiliza API-ul pentru a afisa obiecte bi-dimensionale chiar daca acestea sunt definite prin coordonate (x,y,z) prin plasarea tuturor datelor intr-un singur plan si utilizarea unei proiectii corespunzatoare.\\ | + | OpenGL este un API de grafică tridimensională, adică, toate obiectele care pot fi definite sunt raportate la un sistem de coordonate carteziene tridimensional. Cu toate acestea putem utiliza API-ul pentru a afișa obiecte bi-dimensionale chiar dacă acestea sunt definite prin coordonate (x,y,z) prin plasarea tuturor datelor într-un singur plan și utilizarea unei proiecții corespunzătoare.\\ |
- | In cadrul laboratorului vom utiliza coordonata Z = 0. Astfel orice punct tridimensional va deveni P(x,y,0) | + | În cadrul laboratorului vom utiliza coordonata Z = 0. Astfel orice punct tridimensional va deveni P(x,y,0) |
</note> | </note> | ||
===== Topologie ===== | ===== Topologie ===== | ||
Line 32: | Line 35: | ||
{{ :egc:laboratoare:lab02:topologie_cub.png?nolink |}} | {{ :egc:laboratoare:lab02:topologie_cub.png?nolink |}} | ||
- | Primitiva de baza in OpenGL este triunghiul. Astfel asa cum se poate observa si in imaginea de sus pentru a desena un obiect acesta trebuie specificat prin triunghiuri. | + | Primitiva de bază în OpenGL este triunghiul. Astfel, așa cum se poate observa și în imaginea de sus, pentru a desena un obiect acesta trebuie specificat prin triunghiuri. |
- | Cubul descris mai sus este specificat prin lista celor 8 coordonate de varfuri si o lista de 12 triunghiuri care descrie modul in care trebuie unite varfurile specificate in lista precedenta pentru a forma fețele cubului. | + | Cubul descris mai sus este specificat prin lista celor 8 coordonate de vârfuri și o listă de 12 triunghiuri care descrie modul în care trebuie unite vârfurile specificate în lista precedentă pentru a forma fețele cubului. |
- | Folosind varfuri si indici putem descrie in mod discret orice obiect tridimensional. | + | Folosind vârfuri și indici putem descrie în mod discret orice obiect tridimensional. |
- | Mai jos regasiti principalele primitive acceptate de standardul OpenGL 3.3+. | + | Mai jos regăsiți principalele primitive acceptate de standardul OpenGL 3.3+. |
{{ :egc:laboratoare:lab02:gl_geometric_primitives.png?nolink |}} | {{ :egc:laboratoare:lab02:gl_geometric_primitives.png?nolink |}} | ||
- | Dupa cum se poate observa exista mai multe metode prin care geometria poate fi specificata: | + | După cum se poate observa, există mai multe metode prin care geometria poate fi specificată: |
- | * **GL_LINES** si **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 | ||
- | * Celelalte modele reprezinta doar niste optimizari ale celor 3 primitive de baza, atat din perspectiva memoriei dar si a usurintei in a specifica anumite topologii insa utilitatea lor este deseori limitata intrucat obiectele mai complexe nu pot fi specificate decat prin utilizarea primitivelor simple | + | * Celelalte modele reprezintă doar niște optimizari ale celor 3 primitive de bază, atât din perspectiva memoriei dar și a ușurinței în a specifica anumite topologii însă utilitatea lor este deseori limitată întrucât obiectele mai complexe nu pot fi specificate decât prin utilizarea primitivelor simple |
<note important> | <note important> | ||
- | In cadrul framework-ului puteti seta tipul de primitiva utilizat de catre un obiect la randare prin intermediul functiei [[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 mentionate in 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 specificarii varfurilor ==== | + | ==== Ordinea specificării vârfurilor ==== |
- | O observatie importanta legata de topologie este ordinea varfurilor intr-o primitiva solida (nu linie, nu punct) cu mai mult de 2 varfuri. Aceasta ordine poate fi in sensul acelor de ceas sau in sens invers. | + | O observație importantă legată de topologie este ordinea vârfurilor într-o primitivă solidă (nu linie, nu punct) cu mai mult de 2 vârfuri. Această ordine poate fi în sensul acelor de ceas sau în sens invers. |
{{ :egc:laboratoare:lab02:winding-order-triangle.png?nolink |}} | {{ :egc:laboratoare:lab02:winding-order-triangle.png?nolink |}} | ||
Line 58: | Line 61: | ||
==== Face Culling ==== | ==== Face Culling ==== | ||
- | API-ul OpenGL ofera posibilitatea de a testa orientarea aperenta pe ecran a fiecarui triunghi inainte ca acesta sa fie redat si sa il ignore in functie de stare de discard setata: **GL_FRONT** sau **GL_BACK**. Acesta functionalitatea poarta numele de **[[https://www.opengl.org/wiki/Face_Culling|Face Culling]]** si este foarte importanta 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> | ||
- | Exemplu: pentru un **cub** maxim 3 fete pot fi vizibile la un moment dat, din cele 6 existente. In acest caz maxim 6 triunghiuri vor fi procesate pentru afisarea pe ecran in loc de 12. | + | Exemplu: pentru un **cub** maxim 3 fețe pot fi vizibile la un moment dat din cele 6 existente. În acest caz maxim 6 triunghiuri vor fi procesate pentru afișarea pe ecran în loc de 12. |
</note> | </note> | ||
- | In mod normal face-culling este dezactivat. Acesta poate fi activat folosind comanda [[https://www.opengl.org/sdk/docs/man4/html/glEnable.xhtml|glEnable]]: | + | În mod normal face-culling este dezactivat. Acesta poate fi activat folosind comanda [[https://www.opengl.org/sdk/docs/man4/html/glEnable.xhtml|glEnable]]: |
<code cpp> | <code cpp> | ||
glEnable(GL_CULL_FACE); | glEnable(GL_CULL_FACE); | ||
</code> | </code> | ||
- | Pentru a dezactiva face-culling se foloseste comanda [[https://www.opengl.org/sdk/docs/man4/html/glEnable.xhtml|glDisable]]: | + | Pentru a dezactiva face-culling se folosește comanda [[https://www.opengl.org/sdk/docs/man4/html/glEnable.xhtml|glDisable]]: |
<code cpp> | <code cpp> | ||
glDisable(GL_CULL_FACE); | glDisable(GL_CULL_FACE); | ||
</code> | </code> | ||
- | Pentru a specifica ce orientare a fetelor sa fie ignorata se foloseste comanda **[[https://www.opengl.org/wiki/GLAPI/glCullFace|glCullFace]]** | + | Pentru a specifica ce orientare a fețelor să fie ignorată se folosește comanda **[[https://www.opengl.org/wiki/GLAPI/glCullFace|glCullFace]]** |
<code cpp> | <code cpp> | ||
// GL_FRONT, GL_BACK, and GL_FRONT_AND_BACK are accepted. | // GL_FRONT, GL_BACK, and GL_FRONT_AND_BACK are accepted. | ||
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 varfuri si indici. In laborator aveti posibilitatea sa incarcati meshe in 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]]. |
==== Vertex Buffer Object (VBO) ==== | ==== Vertex Buffer Object (VBO) ==== | ||
- | Un vertex buffer object reprezinta un container in care stocam date ce tin de continutul varfurilor precum: | + | Un vertex buffer object reprezintă un container în care stocăm date ce țin de conținutul vârfurilor precum: |
- | * pozitie | + | * poziție |
- | * normala | + | * normală |
- | * culoarea | + | * culoare |
* coordonate de texturare | * coordonate de texturare | ||
* etc... | * etc... | ||
- | Un vertex buffer object se poatea crea prin comanda OpenGL **[[https://www.opengl.org/sdk/docs/man/html/glGenBuffers.xhtml|glGenBuffers]]**: | + | Un vertex buffer object se poate crea prin comanda OpenGL **[[https://www.opengl.org/sdk/docs/man/html/glGenBuffers.xhtml|glGenBuffers]]**: |
<code cpp> | <code cpp> | ||
GLuint VBO_ID; // ID-ul (nume sau referinta) buffer-ului ce va fi cerut de la GPU | GLuint VBO_ID; // ID-ul (nume sau referinta) buffer-ului ce va fi cerut de la GPU | ||
Line 102: | Line 129: | ||
<note> | <note> | ||
- | Asa cum se poate vedea si din explicatia API-ului, functia [[https://www.opengl.org/sdk/docs/man/html/glGenBuffers.xhtml|glGenBuffers]] primeste numarul de buffere ce trebuie generate cat si locatia din memorie unde vor fi salvate referintele (ID-urile) generate.\\ | + | Așa cum se poate vedea și din explicația API-ului, funcția [[https://www.opengl.org/sdk/docs/man/html/glGenBuffers.xhtml|glGenBuffers]] primește numărul de buffere ce trebuie generate cât și locația din memorie unde vor fi salvate referințele (ID-urile) generate.\\ |
- | In exemplu de mai sus este general doar 1 singur buffer iar ID-ul este salvat in variabila ''VBO_ID''. | + | În exemplul de mai sus este generat doar 1 singur buffer iar ID-ul este salvat în variabila ''VBO_ID''. |
</note> | </note> | ||
- | Pentru a distruge un VBO si astfel sa eliberam memoria de pe **GPU** se foloseste comanda **[[https://www.opengl.org/sdk/docs/man4/html/glDeleteBuffers.xhtml|glDeleteBuffers]]**: | + | Pentru a distruge un VBO și astfel să eliberăm memoria de pe **GPU** se folosește comanda **[[https://www.opengl.org/sdk/docs/man4/html/glDeleteBuffers.xhtml|glDeleteBuffers]]**: |
<code cpp> | <code cpp> | ||
glDeleteBuffers(1, &VBO_ID); | glDeleteBuffers(1, &VBO_ID); | ||
</code> | </code> | ||
- | Pentru a putea pune date intr-un buffer trebuie intai sa legam acest buffer la un „target”. Pentru un vertex buffer acest „binding point” se numeste **GL_ARRAY_BUFFER**, si 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 117: | Line 144: | ||
</code> | </code> | ||
- | In acest moment putem sa facem upload de date din memoria **CPU** catre **GPU** prin intermediul comenzii **[[https://www.opengl.org/sdk/docs/man4/html/glBufferData.xhtml|glBufferData]]**: | + | În acest moment putem să facem upload de date din memoria **CPU** către **GPU** prin intermediul comenzii **[[https://www.opengl.org/sdk/docs/man4/html/glBufferData.xhtml|glBufferData]]**: |
<code cpp> | <code cpp> | ||
Line 123: | Line 150: | ||
</code> | </code> | ||
- | * Comanda citeste de la adresa specificata, in exemplul de sus fiind adresa primului varf ''&vertices[0]'', si copiaza in memoria video dimensiunea specificata prin parametrul al 2-lea. | + | * Comanda citește de la adresa specificată, în exemplul de sus fiind adresa primului vârf ''&vertices[0]'', și copiază în memoria video dimensiunea specificată prin parametrul al 2-lea. |
- | * **GL_STATIC_DRAW** reprezinta un hint pentru driverul video in ceea ce priveste metoda de utilizare a bufferului. Acest simbol poate avea mai multe valori dar in cadrul laboratorului este de ajuns specificarea prezentata. Mai multe informatii gasiti pe pagina de manual a functiei [[https://www.opengl.org/sdk/docs/man4/html/glBufferData.xhtml|glBufferData]] | + | * **GL_STATIC_DRAW** reprezintă un hint pentru driver-ul video în ceea ce privește metoda de utilizare a bufferului. Acest simbol poate avea mai multe valori dar în cadrul laboratorului este de ajuns specificarea prezentată. Mai multe informații găsiți pe pagina de manual a funcției [[https://www.opengl.org/sdk/docs/man4/html/glBufferData.xhtml|glBufferData]] |
<note tip> | <note tip> | ||
- | Pentru a intelege mai bine API-ul OpenGL va rocomandam sa cititi documentatia indicata pentru fiecare comanda prezentata. Atunci cand se prezinta o noua comanda, daca apasati click pe numele acesteia veti fi redirectionati catre 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, documentatia oficiala si completa a API-ului OpenGL poate fi gasita 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> | ||
==== Index Buffer Object (IBO) ==== | ==== Index Buffer Object (IBO) ==== | ||
- | Un index buffer object (numit si element buffer object) reprezinta un container in care stocam indicii vertex-ilor. Cum **VBO** si **IBO** sunt buffere, ele sunt extrem de similare in constructie, incarcare 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 142: | Line 169: | ||
</code> | </code> | ||
- | La fel ca la VBO, creem un IBO si apoi il legam la un punct de legatura, doar ca de data aceasta punctul de legatura este **GL_ELEMENT_ARRAY_BUFFER**. Datele sunt trimise catre bufferul mapat la acest punct de legatura. In cazul indicilor toti vor fi de dimensiunea unui singur intreg. | + | La fel ca la VBO, creăm un IBO și apoi îl legăm la un punct de legatură, doar că de data aceasta punctul de legatură este **GL_ELEMENT_ARRAY_BUFFER**. Datele sunt trimise către bufferul mapat la acest punct de legatură. În cazul indicilor toți vor fi de dimensiunea unui singur întreg. |
==== Vertex Array Object (VAO) ==== | ==== Vertex Array Object (VAO) ==== | ||
- | Intr-un vertex array object putem stoca toata informatia legata de starea geometriei | + | Într-un vertex array object putem stoca toată informația legată de starea geometriei desenate. Putem folosi un număr mare de buffere pentru a stoca fiecare din diferitele atribute („separate buffers”). Putem stoca mai multe (sau toate) atribute într-un singur buffer („interleaved” buffers). În mod normal înainte de fiecare comandă de desenare trebuie specificate toate comenzile de „binding” pentru buffere sau atribute ce descriu datele ce doresc a fi randate. Pentru a simplifica această operație se folosește un vertex array object care ține minte toate aceste legături. |
- | desenate. Putem folosi un numar mare de buffere pentru a stoca fiecare din diferitele atribute („separate buffers”). Putem stoca mai multe(sau toate) atribute intr-un singur buffer („interleaved” buffers). In mod normal inainte de fiecare comanda de desenare trebuie specificate toate comenzile de „binding” pentru buffere sau atribute ce descriu datele ce doresc a fi randate. Pentru a simplifica acesta operatie se foloseste un vertex array object care tine minte toate aceste legaturi. | + | |
- | Un vertex array object este folosind comanda **[[https://www.opengl.org/sdk/docs/man4/html/glGenVertexArrays.xhtml|glGenVertexArrays]]**: | + | Un vertex array object este creat folosind comanda **[[https://www.opengl.org/sdk/docs/man4/html/glGenVertexArrays.xhtml|glGenVertexArrays]]**: |
<code cpp> | <code cpp> | ||
Line 160: | Line 186: | ||
<code cpp>glBindVertexArray(VAO);</code> | <code cpp>glBindVertexArray(VAO);</code> | ||
<hidden> | <hidden> | ||
- | Si este distrus cu **[[https://www.opengl.org/sdk/docs/man4/html/glDeleteVertexArrays.xhtml|glDeleteVertexArrays]]**: | + | Și este distrus cu **[[https://www.opengl.org/sdk/docs/man4/html/glDeleteVertexArrays.xhtml|glDeleteVertexArrays]]**: |
<code cpp>glDeleteVertexArrays(1, &VAO);</code> | <code cpp>glDeleteVertexArrays(1, &VAO);</code> | ||
</hidden> | </hidden> | ||
<note tip> | <note tip> | ||
- | Inainte de a crea VBO-urile si IBO-ul necesar pentru un obiect se va leaga VAO-ul obiectului si acesta va tine minte automat toate legaturile specificate ulterior. | + | Înainte de a crea VBO-urile și IBO-ul necesar pentru un obiect se va lega VAO-ul obiectului și acesta va ține minte automat toate legăturile specificate ulterior. |
- | Dupa ce toate legaturile au fost specificate este recomandat sa dea comanda ''glBindVertexArray(0)'' pentru a dezactiva legatura catre VAO-ul curent, deoarece altfel riscam ca alte comenzi ulterioare OpenGL sa fie legate la acelasi VAO si astfel sa introducem foarte usor erori in program. | + | După ce toate legăturile au fost specificate este recomandat să se dea comanda ''glBindVertexArray(0)'' pentru a dezactiva legătura către VAO-ul curent, deoarece altfel riscăm ca alte comenzi OpenGL ulterioare să fie legate la același VAO și astfel să introducem foarte ușor erori în program. |
</note> | </note> | ||
- | Inainte de comanda de desenare este suficient sa legam doar VAO-ul ca OpenGL sa stie toate legaturile create la constructia 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 201: | ||
==== Descriere laborator ==== | ==== Descriere laborator ==== | ||
- | In cadrul laboratorului vom invata sa folosim **VAO, VBO, IBO** si astfel sa generam si incarcam geometrie simpla.\\ | + | Î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 dispozitie structura [[https://github.com/UPB-Graphics/Framework-EGC/blob/master/Source/Core/GPU/Mesh.h#L14|VertexFormat]] ce va fi utilizata ca baza 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 196: | Line 222: | ||
</code> | </code> | ||
- | Clasa ''Mesh'' pune la dispozitie posibilitatea de a incarca geometrie simpla folosind diverse metode: | + | Clasa ''Mesh'' pune la dispoziție posibilitatea de a încărca geometrie simplă folosind diverse metode: |
<code cpp> | <code cpp> | ||
// 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> | ||
- | Taste de control pentru camera | + | Taste de control pentru cameră |
- | * **W, A, S, D, Q, E** - miscare fata, stanga, spate, dreapta, jos, sus | + | * **W, A, S, D, Q, E** - deplasare față, stânga, spate, dreapta, jos, sus |
- | * **MOUSE RIGHT + MOUSE MOVE** - rotatie camera | + | * **MOUSE RIGHT + MOUSE MOVE** - rotație cameră |
- | **F3** - afisează/ascunde gridul din scena \\ | + | **F3** - afișează/ascunde gridul din scenă \\ |
- | **Space** - deseneaza primitivele doar prin **puncte** sau **linii**(wireframe) sau **geometrie opaca** | + | **Space** - desenează primitivele doar prin **puncte** sau **linii** (wireframe) sau **geometrie opacă** |
</note> | </note> | ||
- | ==== Cerinte laborator ==== | + | ==== Cerințe laborator ==== |
<note important> | <note important> | ||
- | Toate cerintele ce tin de incarcare de geomterie trebuie rezolvate prin intermediul functiei ''Laborator2::CreateMesh'' dar puteti 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> | ||
- | - Descarcati [[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]] |
- | - **(20p)** Completati geometria si topologia unui cub: vectorii de vertecsi si indecsi din initializare. VertexFormat este o structura pentru vertex cu 2 parametri (pozitie, 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). |
- | - **(20p)** Completati functia ''Laborator2::CreateMesh'' astfel incat sa incarcati geometria pe GPU | + | - Completați funcția ''Lab2::CreateMesh'' astfel încât să încărcați geometria pe GPU |
- | * creati un VAO | + | * creați un VAO |
- | * creati un VBO si adaugati date in el | + | * creați un VBO și adăugați date în el |
- | * create un IBO si adaugati date in el | + | * creați un IBO și adăugați date în el |
- | * afisati noul obiect (RenderMesh[cube3]) astfel incat sa nu se suprapuna cu un alt obiect | + | * afișați noul obiect (RenderMesh[cube_B]) astfel încât să nu se suprapună cu un alt obiect |
- | - **(20p)** Creati o noua forma geometrica simpla, de exemplu un tetraedru si desenati-l in scena | + | - Creați o nouă formă geometrică simplă, de exemplu un tetraedru și desenați-l în scenă |
- | - **(20p)** Atunci cand se apasa tasta **F2** faceti toggle intre modul de culling **GL_BACK** si **GL_FRONT** | + | - Atunci când se apasă tasta **F2** faceți toggle între modul de culling **GL_BACK** și **GL_FRONT** |
- | * nu uitati sa activati si sa dezactivati face culling folosind ''glEnable()'' / ''glDisable()'' | + | * nu uitați să activați și să dezactivați face culling folosind ''glEnable()'' / ''glDisable()'' |
- | - **(20p)** Creati un patrat format din 2 triunghi-uri astfel incat fiecare triunghi sa fie vizibil doar dintr-o parte | + | - Creați un pătrat format din 2 triunghiuri astfel încât fiecare triunghi să fie vizibil doar dintr-o parte |
- | * in orice moment de timp nu trebuie sa se vada decat 1 triunghi | + | * în orice moment de timp nu trebuie să se vadă decât 1 triunghi |
- | + | ||
- | ** Total: 100p + Bonus | + | |
<hidden> | <hidden> | ||
Line 246: | Line 270: | ||
Bonusuri posibile: | Bonusuri posibile: | ||
- | - **[Bonus]** Creati un obiect mai complex, format din cel putin 4 fete (tetraedru) astfel incat fiecare fata sa fie desenata cu cate o singura culoare. | + | - **[Bonus]** Folosind ''Mesh::SetDrawMode()'' să se genereze un obiect geometric specificat prin **GL_TRIANGLE_FAN** sau **GL_TRIANGLE_STRIP** sau **GL_LINE_LOOP** |
- | * explicati studentilor de ce e nevoie sa declare fiecare vertex de 3 ori cu culori diferite (in cazul tetraedrului) | + | |
- | - **[Bonus]** Folosind ''Mesh::SetDrawMode()'' sa se genereze un obiet geometric specificat prin **GL_TRIANGLE_FAN** sau **GL_TRIANGLE_STRIP** sau **GL_LINE_LOOP** | + | |
* exemple: | * exemple: | ||
- | * sa se genereze un programabil un cerc avand un numar **N** de laturi | + | * să se genereze programabil un disc de cerc având un număr **N** de laturi |
- | * sa se creeze o interpolare discreta pentru functia sin/cos in intervalul (0, 2PI) folosind **N** linii | + | * să se creeze o interpolare discretă pentru funcția sin/cos în intervalul (0, 2PI) folosind **N** linii |
- | * sa se mareasca/micsoreze numarul **N** prin apasarea unor taste | + | * să se mărească/micșoreze numărul **N** prin apăsarea unor taste |
+ | - **[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) | ||
</hidden> | </hidden> |