Differences

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

Link to this comparison view

ppbg:laboratoare:04 [2023/10/30 21:58]
andrei.lambru
— (current)
Line 1: Line 1:
-====== Laboratorul 04 ====== 
- 
-<note tip> 
-Pentru rezolvarea cerințelor din acest laborator, aveți nevoie de codul utilizat în rezolvarea cerințelor din cadrul laboratorului 3. În situatia în care nu ați rezolvat acest [[:​ppbg:​laboratoare:​03|laboratorul 3]], va trebui să le realizați mai întâi pe el și ulterior să reveniți la cerințele celui curent. 
- 
-**Reamintire!!!** Puteți prezenta rezolvările cerințelor de până la 2 laboratoare,​ în fiecare săptămână. De exemplu, puteți prezenta laboratorul curent și pe cel din săptămâna anterioară,​ în totalitate sau parțial, inclusiv punctajul pentru cerința bonus :) . 
-</​note>​ 
- 
-<note tip> 
-Pentru rezolvarea cerințelor din cadrul acestui labroator: 
-  - [[https://​github.com/​UPB-Graphics/​gfx-framework-ppbg | Descărcați]] framwork-ul de laborator și copiați, din arhiva descărcată,​ directorul **Lab4**, în interiorul directorului //​gfx-framework-ppbg\src\lab//​ din versiunea voastră de proiect. 
-  - Adăugați în fișierul ''​lab_list.h'',​ linia ''#​include "​lab/​lab4/​lab4.h"''​. 
-  - Folosiți din nou utilitarul CMake pentru a regenera proiectul. Pentru a vă reaminti procesul de realizare a setup-ului, puteți să reconsultați [[:​ppbg:​setup-framework | pagina]] dedicată acestui lucru. 
-</​note>​ 
- 
-===== Aplicatiile grafice in timp real ===== 
- 
-===== API-ul grafic OpenGL ===== 
- 
-==== Stergerea ecranului ==== 
- 
-==== Poarta de afisare ==== 
- 
-==== Modele 3D ==== 
- 
-Un model 3D, cunoscut in limba engleza sub numele de **3D mesh**, este un obiect tridimensional definit prin vârfuri și indici. În laborator aveți posibilitatea să încărcați modele 3D î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) === 
- 
-Un vertex buffer object reprezintă un container în care stocăm date ce țin de conținutul vârfurilor precum: 
-  * poziție 
-  * normală 
-  * culoare 
-  * coordonate de texturare 
-  * etc... 
- 
-Un vertex buffer object se poate crea prin comanda OpenGL **[[https://​www.opengl.org/​sdk/​docs/​man/​html/​glGenBuffers.xhtml|glGenBuffers]]**: ​ 
-<code cpp> 
-unsigned int VBO_ID; // ID-ul (nume sau referinta) buffer-ului ce va fi cerut de la GPU 
-glGenBuffers(1,​ &​VBO_ID);​ //​ se genereaza ID-ul (numele) bufferului 
-</​code>​ 
- 
-<​note>​ 
-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.\\ ​ 
-În exemplul de mai sus este generat doar 1 singur buffer iar ID-ul este salvat în variabila ''​VBO_ID''​. 
-</​note>​ 
- 
-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> 
-glDeleteBuffers(1,​ &​VBO_ID);​ 
-</​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]]**:​ 
- 
-<code cpp> 
-glBindBuffer(GL_ARRAY_BUFFER,​ VBO_ID); 
-</​code>​ 
- 
-Î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> 
-glBufferData(GL_ARRAY_BUFFER,​ sizeof(vertices[0]) * vertices.size(),​ &​vertices[0],​ GL_STATIC_DRAW);​ 
-</​code>​ 
- 
-  * 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** 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> 
-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]]** ​ 
-</​note>​ 
- 
-=== 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 în construcție,​ încărcare de date și ștergere. 
- 
-<code cpp> 
-glGenBuffers(1,​ &​IBO_ID);​ 
-glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,​ IBO_ID); 
-glBufferData(GL_ELEMENT_ARRAY_BUFFER,​ sizeof(indices[0]) * indices.size(),​ &​indices[0],​ GL_STATIC_DRAW);​ 
-</​code>​ 
- 
-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) === 
- 
-Î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. 
- 
-Un vertex array object este creat folosind comanda **[[https://​www.opengl.org/​sdk/​docs/​man4/​html/​glGenVertexArrays.xhtml|glGenVertexArrays]]**:​ 
- 
-<code cpp> 
-unsigned int VAO; 
-glGenVertexArrays(1,​ &VAO); 
-</​code>​ 
- 
-Este legat cu **[[https://​www.opengl.org/​sdk/​docs/​man4/​html/​glBindVertexArray.xhtml|glBindVertexArray]]**: ​ 
- 
-<code cpp>​glBindVertexArray(VAO);</​code>​ 
-<​hidden>​ 
-Și este distrus cu **[[https://​www.opengl.org/​sdk/​docs/​man4/​html/​glDeleteVertexArrays.xhtml|glDeleteVertexArrays]]**: ​ 
-<code cpp>​glDeleteVertexArrays(1,​ &​VAO);</​code>​ 
-</​hidden>​ 
-<note tip> 
-Î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. 
- 
-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>​ 
- 
-Î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. 
- 
-==== Optiunea de optimizare Face Culling==== 
- 
-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>​ 
-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>​ 
- 
-Î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> 
-glEnable(GL_CULL_FACE);​ 
-</​code>​ 
- 
-Pentru a dezactiva face-culling se folosește comanda [[https://​www.opengl.org/​sdk/​docs/​man4/​html/​glEnable.xhtml|glDisable]]:​ 
-<code cpp> 
-glDisable(GL_CULL_FACE);​ 
-</​code>​ 
- 
-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> 
-// GL_FRONT, GL_BACK, and GL_FRONT_AND_BACK are accepted. 
-// The initial value is GL_BACK. 
-glCullFace(GL_BACK);​ 
-</​code>​ 
- 
-{{ :​egc:​laboratoare:​lab02:​cull_face.png?​450 |}} 
- 
- 
-===== Cerinte laborator ===== 
  
ppbg/laboratoare/04.1698695904.txt.gz · Last modified: 2023/10/30 21:58 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