This shows you the differences between two versions of the page.
vdvac:lab3 [2024/03/25 16:53] anca.morar [Implementare] |
vdvac:lab3 [2024/03/25 17:45] (current) anca.morar [Demo] |
||
---|---|---|---|
Line 12: | Line 12: | ||
* Culorile fragmentelor rezultate din rasterizarea geometriei proxy sunt acumulate în buffer-ul imagine | * Culorile fragmentelor rezultate din rasterizarea geometriei proxy sunt acumulate în buffer-ul imagine | ||
* Culorile fragmentelor rezultate din rasterizarea unui poligon sunt calculate de hardware-ul plăcii grafice (interpolare biliniară) | * Culorile fragmentelor rezultate din rasterizarea unui poligon sunt calculate de hardware-ul plăcii grafice (interpolare biliniară) | ||
- | * Compunerea culorilor: schema din spate în față, folosind formula $C_{dst} = C_{src} + C_{dst} (1 - A_{src})$ | + | * Compunerea culorilor: schema din spate în față, folosind formula $C_{dst} = C_{src} + C_{dst} (1 - A_{src})$ (se realizează printr-un mecanism de blending) |
* Cazurile ideale: când direcția de vizualizare e perpendiculară pe planele poligoanelor geometriei proxy | * Cazurile ideale: când direcția de vizualizare e perpendiculară pe planele poligoanelor geometriei proxy | ||
* În rest, se alege setul de poligoane care este "cel mai perpendicular" pe direcția de vizualizare | * În rest, se alege setul de poligoane care este "cel mai perpendicular" pe direcția de vizualizare | ||
Line 22: | Line 22: | ||
===== Implementare ===== | ===== Implementare ===== | ||
+ | ==== Atribute ==== | ||
În plus față de elementele din laboratoarele anterioare, se folosesc 3 stive de texturi: <code>unsigned int* textures_idX; | În plus față de elementele din laboratoarele anterioare, se folosesc 3 stive de texturi: <code>unsigned int* textures_idX; | ||
Line 27: | Line 28: | ||
unsigned int* textures_idZ; </code> | unsigned int* textures_idZ; </code> | ||
- | ** Metode ** | + | ==== Metode ==== |
- | * ''load2DTexturesRAW_X()'' generează stiva de texturi de-a lungul axei ''Ox'', citind datele din ''volumeData'' | + | **Generare stive texturi** |
- | * feliile sunt imagini de rezoluție ''ysize * zsize'' | + | |
- | * ''slice'' este iteratorul pentru parcurgerea axei ''Ox'' (la ''volumeData'') | + | |
- | * ''j'' este iteratorul pentru parcurgerea axei ''Oy'', iar ''k'' este iteratorul pentru parcurgerea axei ''Oz'' (atât la ''currentSlice'' cât și la ''volumeData'') | + | |
- | * Atunci (reminder cum se adresează elementele unor matrici multi-dimensionale care sunt liniarizate):<code>currentSlice[k * ysize + j] = ((float)volumeData[k * ysize * xsize + j * xsize + slice]) / 255.0f;</code> | + | |
- | * **Atenție!** În metoda ''load2DTexturesRAW_Y()'', se generează texturi de-a lungul axei ''Oy'', deci feliile sunt imagini de rezoluție ''xsize * zsize'', ''slice'' o sa fie iteratorul pentru parcurgerea axei ''Oy'', ''i'' o sa fie iteratorul pentru parcurgerea axei ''Ox'', iar ''k'', iteratorul pentru parcurgerea axei ''Oz''. Analog și pentru ''load2DTexturesRAW_Z()'' | + | |
- | * ''createPoligX()'' creează un poligon care este în planul ''yOz'', pentru afișarea poligoanelor de-a lungul axei ''Ox'': | + | ''load2DTexturesRAW_X()'' generează stiva de texturi de-a lungul axei ''Ox'', citind datele din ''volumeData'' |
- | * Toate coordonatele ''x'' ale vârfurilor sunt egale cu 0 | + | * feliile sunt imagini de rezoluție ''ysize * zsize'' |
- | * Coordonatele ''y'' și ''z'' sunt coordonatele unui pătrat centrat în origine, de latură 2, în planul ''yOz'': (-1,-1), (1,-1), (1,1) și (-1,1). | + | * ''slice'' este iteratorul pentru parcurgerea axei ''Ox'' (la ''volumeData'') |
- | * Coordonatele de textură ale vârfurilor pătratului sunt în intervalul [0,1]: (0,0), (1,0), (1,1) și (0,1) | + | * ''j'' este iteratorul pentru parcurgerea axei ''Oy'', iar ''k'' este iteratorul pentru parcurgerea axei ''Oz'' (atât la ''currentSlice'' cât și la ''volumeData'') |
- | * ''detMostPerpendicularAxis()'' determină cea mai perpendiculară axă (''Ox / Oy / Oz'') pe planul de vizualizare, și partea (pozitivă / negativă) pe care se află observatorul | + | * Atunci (reminder cum se adresează elementele unor matrici multi-dimensionale care sunt liniarizate):<code>currentSlice[k * ysize + j] = ((float)volumeData[k * ysize * xsize + j * xsize + slice]) / 255.0f;</code> |
- | * Se calculează produsele scalare dintre vectorul de vizualizare și axele principale (''Ox'', ''Oy'' și ''Oz'') | + | * **Atenție!** În metoda ''load2DTexturesRAW_Y()'', se generează texturi de-a lungul axei ''Oy'', deci feliile sunt imagini de rezoluție ''xsize * zsize'', ''slice'' o sa fie iteratorul pentru parcurgerea axei ''Oy'', ''i'' o sa fie iteratorul pentru parcurgerea axei ''Ox'', iar ''k'', iteratorul pentru parcurgerea axei ''Oz''. Analog și pentru ''load2DTexturesRAW_Z()'' |
- | * Se determină cel mai mare produs scalar în valoare absolută. | + | |
- | * Dacă acel produs (fără modul) e pozitiv, înseamnă că observatorul este de partea pozitivă a acelei axe. Pentru acumulare din spate în față, poligoanele se desenează de la cel mai îndepărtat la cel mai apropiat. Astfel, urmează să se deseneze stiva unei axe negative (care pornește de la -1 și merge până la 1) | + | **Creare poligoane în planele principale** |
- | * Dacă produsul e negativ, se desenează stiva unei axe pozitive (care pornește de la 1 și merge până la -1) | + | |
- | * ''DesenStivaAxaXNegativa()'' desenează poligoanele de-a lungul axei Ox, de la cel mai îndepărtat de observator (care are coordonata ''xPos = -1'') până la cel mai apropiat (care are coordonata ''xPos = 1'') | + | ''createPoligX()'' creează un poligon care este în planul ''yOz'', pentru afișarea poligoanelor de-a lungul axei ''Ox'': |
- | * Se pornește cu o matrice de modelare care translatează pătratul din planul yOz la ''xPos = -1'': <code>glm::mat4 model_matrix_slice = glm::translate(glm::mat4(1), glm::vec3(xPos, 0, 0));</code> | + | * Toate coordonatele ''x'' ale vârfurilor sunt egale cu 0 |
- | * Se setează mecanisum de blending: <code>glEnable(GL_BLEND); | + | * Coordonatele ''y'' și ''z'' sunt coordonatele unui pătrat centrat în origine, de latură 2, în planul ''yOz'': (-1,-1), (1,-1), (1,1) și (-1,1). |
+ | * Coordonatele de textură ale vârfurilor pătratului sunt în intervalul [0,1]: (0,0), (1,0), (1,1) și (0,1) | ||
+ | |||
+ | **Determinare stivă de poligoane redate** | ||
+ | |||
+ | ''detMostPerpendicularAxis()'' determină cea mai perpendiculară axă (''Ox / Oy / Oz'') pe planul de vizualizare, și partea (pozitivă / negativă) de care se află observatorul | ||
+ | * Se calculează produsele scalare dintre vectorul de vizualizare și axele principale (''Ox'', ''Oy'' și ''Oz'') | ||
+ | * Se determină cel mai mare produs scalar în valoare absolută. | ||
+ | * Dacă acel produs (fără modul) e pozitiv, înseamnă că observatorul este de partea pozitivă a acelei axe. Pentru acumulare din spate în față, poligoanele se desenează de la cel mai îndepărtat la cel mai apropiat. Astfel, urmează să se deseneze stiva unei axe negative (care pornește de la -1 și merge până la 1) | ||
+ | * Dacă produsul e negativ, se desenează stiva unei axe pozitive (care pornește de la 1 și merge până la -1) | ||
+ | |||
+ | **Desenare stivă poligoane** | ||
+ | |||
+ | ''DesenStivaAxaXNegativa()'' desenează poligoanele de-a lungul axei ''Ox'', de la cel mai îndepărtat de observator (care are coordonata ''xPos = -1'') până la cel mai apropiat (care are coordonata ''xPos = 1'') | ||
+ | * Se pornește cu o matrice de modelare care translatează pătratul din planul ''yOz'' într-un plan paralel cu acesta, dar care are coordonata ''xPos = -1'': <code>glm::mat4 model_matrix_slice = glm::translate(glm::mat4(1), glm::vec3(xPos, 0, 0));</code> | ||
+ | * Se setează mecanismul de blending: <code>glEnable(GL_BLEND); | ||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);</code> | glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);</code> | ||
- | * Funcția aceasta stabilește mecanismul de amestec al culorii. Astfel ''GL_ONE'' este factorul cu care se înmulțește culoarea curentă (culoarea sursă) și ''GL_ONE_MINUS_SRC_ALPHA'' este factorul cu care se înmulțește acumulată (culoarea destinație). | + | * Funcția aceasta stabilește mecanismul de amestec al culorii. Astfel ''GL_ONE'' este factorul cu care se înmulțește culoarea curentă (culoarea sursă) și ''GL_ONE_MINUS_SRC_ALPHA'' este factorul cu care se înmulțește culoarea acumulată (culoarea destinație). |
- | * Se respectă formula $C_{dst} = C_{src} + C_{dst} (1 - A_{src})$ | + | * Se respectă formula $C_{dst} = C_{src} + C_{dst} (1 - A_{src})$ |
- | * Se desenează atâtea pătrate cât este dimensiunea ''xsize'' a volumului | + | * Se desenează atâtea pătrate cât este dimensiunea ''xsize'' a volumului |
- | * După fiecare desenare, se actualizează ''xPos'' | + | * După fiecare desenare, se actualizează ''xPos'' (ca să ajungă de la -1 la 1) |
- | * ''DesenStivaAxaXNegativa()'' desenează poligoanele de-a lungul axei Ox, de la cel mai îndepărtat (care are coordonata ''xPos = 1'') până la cel mai apropiat (care are coordonata ''xPos = -1''). Analog pentru axele ''Oy'' și ''Oz''. | + | * ''DesenStivaAxaXNegativa()'' desenează poligoanele de-a lungul axei Ox, de la cel mai îndepărtat (care are coordonata ''xPos = 1'') până la cel mai apropiat (care are coordonata ''xPos = -1''). Analog pentru axele ''Oy'' și ''Oz''. |
+ | |||
+ | ==== Demo ==== | ||
+ | |||
+ | <html> | ||
+ | <p style="text-align:center;margin:auto;"> | ||
+ | <iframe width="430" height="250" src="https://www.youtube.com/embed/LiY6FlgQrew" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> | ||
+ | </p> | ||
+ | </html> |