Corso di DirectX

Il primo programma DirectX

 

Dopo le pagine introduttive, è tempo di mettersi alla tastiera. Scoprirete che non avrete bisogno di un dattilografo: imparando una libreria complessa come quella DirectX, si passa molto più tempo a spremere le meningi sull’help in linea che a scrivere del codice. E subito dopo, ci vuole di più a cercare di capire come mai non funziona come dovrebbe, piuttosto che a riscriverlo (come sicuramente accadrà due o tre volte di fila :-)
La prima cosa da mettere in chiaro è che un programma DirectX è a tutti gli effetti un programma per Windows: la parte grafica o sonora è solo un’aggiunta, importante o meno, ma la base resta la stessa. E’ possibile integrare i "nuovi" effetti in un vecchio programma, oppure mescolare disegni tradizionali con la GDI e riflessioni in 3D (notate che dico "possibile", e non "facile"...).

Questa dipendenza porta con sé vantaggi e svantaggi. Tra i primi l’evidente integrazione col sistema, e il funzionamento message-driven del programma (se non sapete di cosa sto parlando, non preoccupatevi, vedremo poi cosa significa). Lo svantaggio è che, anche se prevediamo di usare quasi esclusivamente le funzioni DirectX, il nostro programma dovrà avere una certa quantità di codice accessorio, necessario per funzionare bene ed essere un buon vicino di casa. In realtà non è un grosso problema: una volta scritto, questo codice accessorio può essere riutilizzato quasi senza modifiche. Per non appesantire la lezione, non scriverò troppi dettagli: tutti i files necessari sono in questo archivio zip, che è un workspace pronto per il vostro Visual C++ (e prima che qualcuno di voi mi faccia notare che quei files somigliano molto ai primi due tutorial della Microsoft, beh, usate il cervello... più che altro ho cambiato lo stile, che a me non piaceva :-)

Creare l’oggetto Direct3D.

Per prima cosa, dobbiamo creare l’oggetto Direct3D. E’ molto semplice:

IDirect3D8* g_pD3D;
if ( (g_pD3D = Direct3DCreate8( D3D_SDK_VERSION)) == NULL)
    return E_FAIL;

Il puntatore g_pD3D (forse vi conviene scegliere un nome migliore!!) adesso contiene l’indirizzo di un oggetto Direct3D. Cosa ce ne facciamo? Serve ad ottenere informazioni "ad alto livello", come per esempio il tipo di schermo (colori, risoluzioni) che abbiamo a disposizione:

D3DDISPLAYMODE d3ddm;
if ( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm)))
    return E_FAIL;

Con questo metodo possiamo riempire la struttura d3ddm. Vi riporto qui la sua definizione:

typedef struct _D3DDISPLAYMODE {
    UINT            Width;
    UINT            Height;
    UINT            RefreshRate;
    D3DFORMAT       Format;
} D3DDISPLAYMODE;

In questo modo possiamo sapere l’altezza e la larghezza dello schermo, e il suo refresh rate. Inoltre, il parametro Format contiene un valore che specifica in dettaglio la profondità di colore dello schermo. Quest’ultimo valore è quello che ci interessa di più, perché il Direct3d Device ha bisogno di sapere come sono memorizzati i singoli pixel dello schermo.

A questo punto bisogna creare il 3dDevice, con il metodo CreateDevice(). Useremo spesso questo device.

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed   = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;

IDirect3DDevice8* g_pd3dDevice;
if ( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice)))
    return E_FAIL;

Per poter creare il device, dobbiamo specificare molti parametri: tramite la struttura D3DPRESENT_PARAMETERS diciamo che  gireremo in finestra, che usiamo un certo metodo di swap (vedremo in seguito cosa vuol dire), e specifichiamo il formato della profondità di colore prendendolo da d3ddm. Quindi creiamo il device, aggiungendo qualche altro parametro. Come vi ho già accennato prima, per adesso lasciamo molte cose in sospeso (in "default") e ci concentriamo su quello che possiamo capire. Per i dettagli siamo sempre in tempo. L’unica cosa che vi faccio notare è il parametro “D3DCREATE_SOFTWARE_VERTEXPROCESSING”: in questo modo ignoriamo le accelerazioni hardware T&L presenti su molte schede grafiche. Per adesso non importa, ma in seguito faremo qualche esperimento per vedere la differenza.
 (segue nella prossima lezione...)

 

Torna all'indice Generale del corso di Corso di DirectX di Software Planet