\\ Home : Articoli : Stampa
Introduzione a DirectX 10 - prima parte
Di RobyDx (del 03/02/2007 @ 00:31:27, in Direct3D10, linkato 4256 volte)

Benvenuti al primo tutorial della nuova serie di lezioni dedicate a DirectX10. Per chi fosse completamente nuovo al mondo della programmazione grafica, ed in particolare di DirectX, possiamo riassumere che questa è una API, ovvero librerie software messe a disposizione dei programmatori, con cui vengono realizzati giochi ed applicazioni grafiche per PC ed alcune consolle (come l'XBox 360).

Insieme alla concorrente open source OpenGL è usata per il 99% (se non il cento) di tutte le applicazioni grafiche per computer e console.

DirectX offre una serie di componenti e funzioni per poter gestire grafica 2D e 3D, audio, input da tastiera, mouse e periferiche di gioco (come joypad e volanti ad esempio), e funzionalità di rete (per aiutarvi ad inserire le modalità multiplayer). Nel corso degli anni DirectX si è evoluta in modo continuo segnando lo sviluppo dell'hardware, in particolare delle schede video che evolvono insieme a DirectX.

La nuova versione di DirectX10 è sicuramente la quella che ha dato un taglio netto con il passato, eliminando tutto ciò che era considerato obsoleto nelle precedenti.

Chi viene dalle precedenti versioni noterà subito molte differenze come l’assenza di Lost Device (ossia la gestione delle risorse che ora è completamente automatizzata) e dei Caps (le funzionalità di controllo della scheda video, sparite perché le schede DirectX10 supporteranno l’intera libreria senza alcuna incompatibilità).

Altro fondamentale cambiamento, il motivo per cui inizio la nuova serie di tutorial senza il canonico “Hello World” è la completa eliminazione della fixed pipeline.

Per chi non sapesse di cosa sto parlando possiamo riassumere descrivendo l’evoluzione delle ultime 3 versioni di DirectX.

DirectX7 utilizzava come sistema di gestione degli oggetti 3D la fixed pipeline, ossia un insieme di algoritmi definiti in DirectX che partendo dalla descrizione della scena generavano l’immagine finale sullo schermo. Il programmatore poteva solo deciderne le caratteristiche, come il numero di luci accese, la trasparenza, la posizione. Tutto ciò che non era definito nella fixed pipeline doveva essere gestito dall’utente utilizzando la CPU invece che la scheda video. Il risultato era che molti effetti erano irrealizzabili.

(Half Life Valve Sviluppato in DirectX7 da Valve nel 1998)

DirectX8 introdusse la tecnologia shader. Uno shader è un frammento di codice che sostituisce la fixed pipeline nell’elaborazione dei modelli 3D. Ne vengono introdotti 2 tipi.

  1. Vertex Shader, responsabile della gestione dei vertici geometrici degli oggetti 3D
  2. Pixel Shader, responsabile della gestione dei pixel

I programmatori poterono creare nuove procedure ed effetti facendoli gestire direttamente alla scheda video tramite shader. La qualità migliorò in modo notevole nonostante i limiti degli shader per DirectX8.

(Max Payne sviluppato in DirectX8 da Remedy Entertainment nel 2001)

Con DirectX9 gli shader trovano la loro maturità. Nasce HLSL, un linguaggio simil C molto semplice per scrivere shader e tutti i limiti vengono eliminati.

(Unreal Tournament 3 sviluppato da Epic in DirectX9 in uscita per PC nel 2007)

DirectX10 inserisce molte altre funzionalità ed un nuovo tipo di shader: il Geometry Shader. Questo nuovo shader permette di fare qualcosa di completamente nuovo: aggiungere ed eliminare poligoni utilizzando l’hardware della scheda video. Unite ad altre funzionalità è possibile limitare al massimo l’uso della CPU e raggiungere qualità grafiche vicine al fotorealismo.

environmentset7

(Motore Grafico CryEngine 2 in fase di sviluppo da parte di CryTek usa le DirectX10)

Le novità non si limitano a questo ma avremo tempo per approfondire.

Introduzione alle applicazioni Real Time

Una applicazione grafica in Real Time è un programma che genera immagini in sequenza con una velocità sufficiente ad ingannare l’occhio facendogli credere che esse siano in movimento. Una velocità di 16 fps (frame per second) è sufficiente allo scopo ma aumentandone il numero otterremo una migliore fluidità (di solito i giochi si attestano dai 30 ai 60 fps). Esistono 2 tipi di grafica, bidimensionale (2D) o tridimensionale (3D). La modalità di funzionamento è abbastanza differente. La grafica 2D si basa sullo spostamento di zone di memoria: si carica una immagine e la si copia sull’area di memoria che finirà sullo schermo. La grafica 3D invece funziona in maniera molto differente.

Un oggetto 3D (chiamato anche mesh) è un insieme di triangoli piani disposti nello spazio. Non importa quanto un oggetto possa sembrare rotondo, avvicinandoci abbastanza potremo vedere sempre che esso è composto da tanti triangoli. Un cubo, ad esempio, ha 6 facce quadrate ed ogni faccia è composta di almeno 2 triangoli. Sono sufficienti 12 triangoli per generare il nostro cubo. Ogni triangolo è a sua volta composto da 3 punti (Vertici).

Le librerie grafiche prendono queste informazioni, le elaborano e mandano a video i risultati.

Questo processo si chiama rendering. Gli oggetti 3D sono conservati in speciali strutture dati contenenti varie informazioni.

  1. VertexBuffer contenente i punti che compongono il modello 3D. Portano con se oltre alla posizione anche altri valori numerici che possono essere usati per qualsiasi tipo di dato.
  2. IndexBuffer contenente l’ordine con cui i punti vanno presi per formare il modello 3D. Questo perché molti vertici vengono utilizzati per più di un triangolo e con questo sistema si evitano ripetizioni. Prendete l’esempio del cubo. Con 12 triangoli la mesh dovrebbe contenere 36 vertici che, considerando 3 float per rappresentare le coordinate XYZ fanno la bellezza di 12byte x 36 vertici = 432 byte ma in realtà solo 8 vertici sono unici (96 byte). Associando un array di short che li ordina bastano 36 valori, 72 byte che sommati agli 8 vertici fanno 168 byte, un terzo del totale.

Le mesh vengono create solitamente tramite editor (ma nulla vieta di crearle da codice con procedure automatizzate) e caricate da file. Al momento del caricamento queste si trovano nella posizione che avevano nell’editor. Sarà la fase di rendering ad impostare, fotogramma per fotogramma, l’oggetto nella sua posizione finale per poi mostrarlo a video.

continua nella seconda parte...