Cerca nel sito:

Programmazione Video Giochi in OpenGL e C++ (parte 2/2)

Di Gianluca Panebianco, Data di pubblicazione: 11 Novembre 2003, Ultimo aggiornamento: 11 Novembre 2003

2. Oggetti, finestre, metodi

Qualsiasi oggetto in OpenGL è costruito a partire dagli oggetti geometrici di base: le primitive punto, linea e poligono. In OpenGL si realizza quello che viene detto immediate-mode graphics, ovvero ogni volta che viene eseguito un comando di disegno l'oggetto specificato viene disegnato. Questo differisce da altri sistemi in cui vengono fatte inizialmente delle operazioni e viene creata una lista di cose da disegnare, e solo successivamente viene detto all'hardware grafico di rappresentare tutti gli oggetti nella lista.

Cancellare la finestra, selezionare un colore e forzare il disegno sono elementi fondamentali per OpenGL. Esistono comandi specifici per ognuna di queste operazioni.

Un'altra proprietà importante è la rimozione della superficie nascosta. In questo modo si evitano di disegnare parti nascoste da altri oggetti. Questa rimozione si ottiene tramite il depth buffer (anche detto z-buffer), che associa un aprofondità, o distanza dal punto di vista, ad ogni pixel presente sulla finestra.
I calcoli grafici convertono ogni superficie che deve essere disegnata in un insieme di pixel sulla finestra. Se il depth buffer è abilitato, prima che ogni pixel sia disegnato viene fatto un confronto col valore già immagazzinato nel pixel. Se la profondità del nuovo pixel è minore di quella del precedente, allora viene disegnato questo pixel. Se è maggiore, l'informazione viene scartata (e proprio lo scartare invece del disegnare comunque migliora le prestazioni con questa tecnica).Lightwave 3d programming
Per usare il depth buffer bisogna abilitarlo. Questo va fatto solo una volta. Poi, però, ogni volte che si disegna una scena, prima di disegnare bisogna cancellare il buffer.

Molti moderni sistemi grafici possono essere pensati come una assembly line chiamata pipeline. La CPU invia i comandi di disegno e degli hardware dedicati si occupano della loro effettiva esecuzione. Tali comandi possono essere inviati anche per rete; in questo caso essi sono raccolti in pacchetti per aumentare l'efficienza della rete. Sfortunatamente, la rete non ha comandi per sapere se un disegno è terminato o meno. In questo caso la CPU potrebbe aspettare per sempre prima di riempire un nuovo pacchetto e spedirlo (e il disegno non verrebbe mai completato).
Per questo motivo OpenGL fornisce due comandi per forzare il disegno: glFlush() e glFinish(). Il primo forza un pacchetto ad essere inviato anche se non è ancora pieno (fa eseguire i comandi), garantendo così che i comandi siano eseguiti entro un tempo finito. Il secondo aspetta un messaggio di conferma dall'hardware grafico che il disegno sia stato completato (garantendo così che esso appaia correttamente). Dopo aver usato questo comando, il processo grafico è bloccato fino all'arrivo della notifica. Ovviamente è più lento e complesso del primo e per questo la performace del sistema diminuisce se lo si utilizza frequentemente.

3. Punti, linee e poligoni

Quando esegue calcoli, OpenGL assume un punto come rappresentato da un vettore di numeri floating point (anche se esso è tipicamente disegnato semplicemente come un pixel), detto vertice. Tutti i calcoli interni sono fatti come se il punto fosse tridimensionale (anche se l'utente assegna solo le coordinate x, y e z viene posto = 0 da OpenGL).
Le linee sono espresse in termini dei loro vertici e di eventuali endpoint (se la line rsisulta chiusa).
Un poligono è un'area racchiusa da un insieme di segmenti di linea (ciclo chiuso di linee); di solito viene disegnato riempito.
Poichè essi possono essere molto complessi, OpenGL pone delle restrizioni su quelle che sono le primitive di tali figure:
1- i lati di un poligono non possono intersecarsi;
2- devono essere convessi (insiemi convessi).
Poligono più complessi possono essere ottenuti dall'unione di quelli semplici, e nella GLU esistono diverse routine che fanno proprio questo (tesellation routines).
Poichè i punti sono considerati in tre dimensioni, si può ottenere un poligono non semplice anche ruotando alcuni punti su altri piani; il risultato a schermo sarà qualcosa di più complesso, ma per OpenGL sarà sempre un poligono semplice.

Anche i rettangoli e le curve sono considerati figure primitive, e dispongono di comandi appositi.

Una qualsiasi di queste primitive viene disegnata specificando i vertici (tramite glVertex*() ) tra le due istruzioni glBegin() e glEnd() (in particolare glBegin permette di specificare il tipo di primitiva che si sta disegnando).

E' possibile definire la larghezza delle linee ed il tipo di tratto (disegno a punteggiatura).

I poligono per default sono disegnati riempiti, ma possono essere anche rappresentati semplicemente tramite punti o con le sole linee del perimetro.
Per convenzione i poligoni i cui vertici appaiono in ordine antiorario sullo schermo sono detti front facing (faccia davanti).
E' possibile cambiare l'orientamento delle facce (fronte - retro), attraverso il comando glFrontFace(). E' possibile fare disegnare solo i poligoni frontali (o solo quelli dietro) tramite il comando glCullFace() (che dice quali poligoni scartare).

I poligoni non convessi possono essere disegnati come l'unione di poligoni convessi più semplici. Se però si vuole disegnare il poligono concavo solo tramite le linee perimetrali, è necessario usare la funzione glEdgeFlag() che permette di definire i vertici come l'inizio di un lato di perimetro o come punti interni, permettendo così di non disegnare tutte le linee di un poligono composto in realtà da poligoni più semplici, facendolo apparire come un unico poligono non convesso.

Davide Di Giulio è un esperto programmatore C++. Nell'ultimo anno si è specializzato nella programmazione delle librerie OpenGL in ambiente Windows con scopo di visualizzazione 2D e 3D realtime di geometrie complesse a supporto della produttività aziendale.
Davide ha anche un sito, potete accedervi a questo indirizzo: Davide Di Giulio Homepage

Programmazione Video Giochi in OpenGL e C++
< Precedente 1 2 Successivo >



Inserisci il tuo commento