Informatica Grafica ][ Marco Gribaudo marcog@di.unito.it Grafica 3D Interattiva sono una libreria di funzioni a basso livello per facilitare la scrittura di videogiochi e di applicazioni multimediali. Esistono ormai numerose versioni delle DirectX. Noi utilizzeremo le DirectX 8.1, in quanto l'ultima versione disponibile sia per C++ che Visual Basic. A partire dalla versione 9 le DirectX sono state integrate nell'architettura.net di Microsoft e ciò ne ha complicato ulteriormente l'utilizzo. 9 garantiscono comunque compatibilita' all'indietro con la versione 8. 8 si suddividono nelle seguenti componenti: DirectX Audio DirectPlay DirectInput Le includono le funzioni per gestire tanto la grafica 3D che quella 2D. Nelle precedenti versioni della libreria queste due componenti erano distinte (denominate rispettivamente Direct3D e DirectDraw) A partire dalla versione 8, le due componenti sono state unite in un'unica libreria. Audio si dividono in due componenti: DirectSuond e DirectMusic DirectSound si occupa della riproduzione e della localizzazione spaziale dei suoni. DirectMusic si occupa di riprodurre intere sequenze musicali per costituire la colonna sonora che accompagna un'applicazione. DirectInput gestisce l'interazione con le periferiche di gioco (Jostick, Gamepad etc...) DirectPlay si occupa invece della comunicazione attraverso la rete, in modo da facilitare la creazione di giochi multiplayer.
In questo corso utilizzeremo in particolare le, e parte delle DirectInput. DirectX Audio DirectPlay DirectInput Le sono particolarmente efficienti nello sfruttare le caratteristiche specifiche di accelerazione delle schede video utilizzando un supporto chiamato HAL (Hardware Abstraction Layer) Ogni scheda video fornisce, oltre ai suoi Driver, un insieme di procedure che eseguono funzionalita' di basso livello (l'hal, appunto) Qualora una scheda non supporti un particolare tipo di funzionalita' in hardware, il suo HAL si occupa di emularla via software. Questo grafico paragona le alle normali primitive grafiche di Windows (GDI). Come spiegato in precedenza, le DirectX forniscono prevalentement procedure per i primi livelli di un motore di Rendering. La visualizzazione avviene mediante un flusso di elaborazioni detto Pipeline. Una Pipeline e' una sequenza di operazioni nella quale ogni stadio elabora le informazioni prodotte dallo stadio precedente e le passa allo stadio successivo. La seguente figura mostra gli stadi della Pipeline delle DirectX graphics: I vertici dei poligoni e le primitive grafiche, vengono forniti come input iniziale all'intero processo. La fase di tessellazione suddivide se necessario tali primitive grafiche in triangoli piu' piccoli.
I dati ottenuti, possono quindi essere trasformati attraverso una modalita' standard (Fixed Function Pipeline), oppure attraverso una modalita' personalizzata (Programmable Pipeline) Quindi avvengono le procedure di eliminazione delle superfici nascoste (Clipping, Backface culling...) Parallelamente, DirectX graphics puo' lavorare sulle Texture e sfruttarle per stabilire i colori dei Pixel (Texture Surface, Texture Sampler e Pixel Shader). Infine i triangoli vengono disegnati sulla scheda video, applicando i controlli di Z-buffer, trasparenza, etc... In pratica, l'intera Pipeline di, esegue le funzionalita' richieste dai primi due livelli di un motore di rendering. Livello di Proiezione e clipping (II livello) Livello di disegno dei triangoli (I livello) Per poter realizzare un'applicazione che visualizzi grafica 3D bisogna introdurre almeno una cinepresa ed una luce. Mentre nei programmi di grafica 3D come 3D studio o Maya si possono utilizzare quelle definite implicitamente dalla viewport, in un motore di rendering essi devono essere definiti esplicitamente. Dal momento che le procedure necessarie alla creazione di cineprese e luci utilizzano come parametri i vettori, occorre creare una procedura di ausilio per poterli definire: Nelle lezioni successive vedremo come definire e spostare cineprese e luci. In questo esercizio, ci limiteremo alla creazione di una cinepresa che punti verso l'origine degli assi del mondo tridimensionale e di una luce puntiforme fissa.
Il passo successivo consiste nel cambiare i tipi di vertici: infatti per agire in tre dimensioni, questi devono essere "non trasformati". Bisogna poi anche cambiare il comando che imposta la modalita' dei vertici E' stato rimosso rwh As Single definito in precedenza In precedenza era impostato a D3DFVF_XYZRWH...ed anche le definizioni dei vertici della figura: si devono eliminare i valori di w, e cambiare le coordinate x,y,z in quanto si passa da coordinate schermo a coordinate cartesiane. Si devono poi aggiungere le definizioni delle variabili utilizzate per memorizzare le impostazioni della cinepresa. Ed infine aggiungere le chiamate per impostare la cinepresa al termine della fase di inizializzazione dell'applicazione. Si puo' quindi finalmente provare l'applicazione. Essa visualizzera' sempre un triangolo, ma questa volta esso sara' una proiezione di un triangolo in tre dimensioni!
Per introdurre una luce bisogna modificare nuovamente le definizioni dei vertici, in modo da aggiungere i valori delle normali alle superfici. Le specifiche dei vertici devono quindi essere cambiate di conseguenza, in modo da inidcare anche i valori per le normali. Bisogna aggiungere una variabile per contenere i dati della luce. Modificare le funzioni di inizializzazione della libreria in modo che includano la gestione delle luci. Si deve anche cambiare il comando di cancellazione dello schermo, in modo che riempia il fondale di colore nero. Ed infine attivare le luci al termine della fase di inizializzazione dell'applicazione.
Provando nuovamente l'applicazione, essa visualizzera' un triangolo, la cui superficie risulta sfumata in base al modello di illuminazione. Definire i vertici di un poligono richiede di impostare diversi campi di una medesima struttura. Per ridurre la quantita' di codice necessaria, Visual Basic mette a disposizione il comando With. Il comando With specifica un blocco all'interno del quale tutti i campi si riferiscono ad un medesimo oggetto. E' necessario specificare il nome dell'oggetto subito dopo la parola With. All'interno del blocco, tutti i campi preceduti da un punto "." si considerano implicitamente riferiti all'oggetto indicato. Diventa Utilizzando congiuntamente il simbolo : per condensare piu' comandi su una unica riga, si puo' ulteriormente diminuire lo spazio utilizzato dalla definizione dei vertici del triangolo.