This shows you the differences between two versions of the page.
|
egc:laboratoare:02 [2018/09/28 09:50] alexandru.gradinaru [Cerinte laborator] |
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 ===== | ||
| - | 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]] |
| - | - **(25p)** Completati functia ''Laborator2::CreateMesh'' astfel incat sa incarcati geometria pe GPU | + | - 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). |
| - | * creati un VAO | + | - Completați funcția ''Lab2::CreateMesh'' astfel încât să încărcați geometria pe GPU |
| - | * creati un VBO si adaugati date in el | + | * creați un VAO |
| - | * create un IBO si adaugati date in el | + | * creați un VBO și adăugați date în el |
| - | * comentati functiile InitFromData (ex: meshes["cube1"]->InitFromData(vertices, indices);) | + | * creați un IBO și adăugați date în el |
| - | * adaugati la lista de meshe (meshes[]) si desenati obiectul creat cu ''CreateMesh'' ("cube3") | + | * afișați noul obiect (RenderMesh[cube_B]) astfel încât să nu se suprapună cu un alt obiect |
| - | - **(25p)** 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ă |
| - | - **(25p)** 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()'' |
| - | - **(25p)** 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) | ||
| + | - **[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> | ||