Le
novità e l'importazione della libreria nel progetto |
La
libreria DirectX8 è piuttosto differente dalle versioni
precedenti. Un elemento che avrà sicuramente lasciato
perplesso è la mancanza dell'interfaccia DirectDraw
esistente fino alla settima versione.
Ma mentre nelle DirectX7 si poteva utilizzare Direct3D come
metodo per generare grafica bidimensionale (unitamente a DirectDraw),
adesso questo è l'unica strada possibile.
In ogni caso i nuovi aspetti delle DirectX verranno analizzati
in dettaglio nel corso di questi articoli. Cominciamo subito
a preparare il progetto dicendo che per poter utilizzare la
libreria DirectX8 è innanzitutto necessario importarla
nel progetto.
Naturalmente
se non si dispone della libreria DirectX8 essa non comparirà
nella lista dei riferimenti disponibili. Inoltre tale libreria
è utilizzabile solamente da chi dispone una versione
di Visual Basic superiore alla quarta (visto che prima non
era in uso il Component Object Model (COM) ).
Inizializzare
gli oggetti DirectX8, Direct3D8, Direct3DDevice8 |
Il
secondo passo è quello di dichiarare tutte le variabili
e gli oggetti presenti nel progetto. Innanzitutto c'è
da considerare l'oggetto principale ossia DirectX8 la cui
istanza può essere denominata Dx:
L'intera
struttura dell'applicazione si diramerà partendo proprio
da tale oggetto. In secondo luogo troviamo l'oggetto che gestisce
la parte grafica dell'applicazione ossia Direct3D8.
Si può denominare la sua istanza come D3D:
Quello
che ci serve adesso è una variabile booleana che ci
indichi in ogni momento se l'applicazione è in esecuzione
o meno. Nel primo caso quindi assumerà valore True
mentre nel secondo False.
Tale variabile si rivelerà utile in futuro. Chiamiamola
'Esecuzione':
Dim
Esecuzione As Boolean |
Inoltre
nelle dichiarazioni bisogna tener conto del tipo di hardware
che processa la grafica ossia se la visualizzazione delle
immagini è gestita direttamente dal processore oppure
è dalla scheda video.
L'oggetto che rappresenta l'hardware utilizzato è Direct3DDevice8
la cui istanza chiameremo D3DDevice:
Dim
D3DDevice As Direct3DDevice8
|
Ecco
quindi qui sotto le dichiarazioni generali utili in questo
primo articolo:
Dim
DX As DirectX8
Dim D3D As
Direct3D8
Dim D3DDevice As
Direct3DDevice8
Dim Esecuzione As
Boolean |
Quando
si progetta un'applicazione che fa uso delle DirectX è
buona norma creare una funzione di inizializzazione. Tale
funzione non fa altro che assegnare dei parametri standard
ai vari oggetti in modo da settarli in modo corretto in vista
di un successivo utilizzo.
Il valore ritornato dalla funzione è un valore booleano
per cui in caso di corretta inizializzazione degli oggetti
si otterrà True mentre in caso contrario si otterrà
False.
Chiamiamo la funzione Inizializzazione. Al suo interno
dovremo innanzitutto determinare il tipo di visualizzazione.
Possiamo denominare la variabile alla quale assegnare la modalità
di visualizzazione come 'Visualizzazione' che non è
altro che un memro della struttura D3DDISPLAYMODE:
Private
Function Inizializza()
As Boolean
Dim Visualizzazione As
D3DDISPLAYMODE
End Function |
Per
approfondire ulteriormente l'argomento e per comprendere meglio
di cosa si parla col termine visualizzazione aggiungiamo che
la struttura D3DDISPLAYMODE ha la seguente sintassi:
Type
D3DDISPLAYMODE
Format As CONST_D3DFORMAT
Height As Long
RefreshRate As Long
Width As Long
End Type |
dove
Format è un puntatore ad una struttura del tipo
CONST_D3DFORMAT la cui analisi va oltre lo scopo di questo
articolo, Height è invece l'altezza in pixel
dello schermo, RefreshRate indica la velocità
con cui le immagini passano dalla memoria video allo schermo
e Width è la larghezza in pixel dello schermo.
Naturalmente, dopo aver incluso la funzione nel progetto sarà
necessario richiamarla dalla routine Form_Load indicando semplicemente,
prima di End Sub:
Private
Sub
Form_Load()
Inizializza
End Sub |
All'ultima
dichiarazione vista c'è da aggiungere alla funzione
la dichiarazione del membro della struttura D3DPRESENT_PARAMETERS
che contiene i parametri di visualizzazione della finestra
di esecuzione dell'applicazione. Come si può leggere
dall'articolo Le API: approfondimenti sul concetto di struttura:
tipi definiti dall'utente , utilizzare una variabile definita
da una struttra impostata dall'utente significa fare uso di
un tipo di variabile utilizzabile in modo del tutto normale
ma che racchiude i dati della struttura. Più avanti
comunque si capirà meglio il concetto:
Dim
D3DWindow As D3DPRESENT_PARAMETERS
|
La
struttura D3DPRESENT_PARAMETERS infatti è la
seguente. In realtà i concetti ai quali fa riferimento
la struttura sono avanzati e non verranno utilizzati per un
po' di tempo (tranne il parametro Windowed). Quindi non ci
si deve allarmare ma eventualmente tornare a recuperare le
informazioni contenute in essa quando verranno trattate più
avanti:
Type
D3DPRESENT_PARAMETERS
AutoDepthStencilFormat As
CONST_D3DFORMAT
BackBufferCount As Long
BackBufferFormat As CONST_D3DFORMAT
BackBufferHeight As Long
BackBufferWidth As Long
EnableAutoDepthStencil As Long
Flags As Long
FullScreen_PresentationInterval As
Long
FullScreen_RefreshRateInHz As Long
hDeviceWindow As Long
MultiSampleType As CONST_D3DMULTISAMPLE_TYPE
SwapEffect As CONST_D3DSWAPEFFECT
Windowed As Long
End Type |
dove
AutoDepthStencilFormat è un puntatore alla struttura
CONST_D3DFORMAT che determina il formato della superficie
che viene creata automaticamente dallo strumento che gestisce
la grafica (scheda video oppure scheda acceleratrice). Questo
parametro è generalmente ignorato a meno che non se
ne indichi espressamente un valore diverso da 0.
Per comprendere il secondo parametro, BackBufferCount,
è necessario avere un'idea generica del concetto di
BackBuffer che comunuqe verrà trattato nel dettaglio
più avanti. Basterà sapere per adesso che BackBuffer
è quella porzione di memoria nella quale le immagini
vengono memorizzate appena prima di essere visualizzate sullo
schermo.
Viene invece definito FrontBuffer la porzione di memoria
che immagazzina l'immagine correntemente visualizzata sullo
schermo.
Allora BackBufferCount è il numero di porzioni di memoria
BackBuffer presenti il valore può andare da un massimo
di 3 ad un minimo di 1 (o 0 visto che in questo caso 0 non
indica l'assenza di un BackBuffer ma indica il numero minimo
ossia 1).
BackBufferFormat è un membro della struttura CONST_D3DFORMAT
che determina il formato delle immagini inserite nel BackBuffer.
BackBufferHeight e BackBufferWidth sono rispettivamente
l'altezza e la larghezza delle immagini inserite nel BackBuffer
(e quindi del BackBuffer stesso se lo si considera come una
superficie).
EnableAutoDepthStencil abilita il parametro AutoDepthStencilFormat,
mentre Flags non è utilizzato quindi deve essere
impostato su 0. FullScreen_PresentationInterval è
un membro della sruttura D3DCAPS8, FullScreen_RefreshRateInHz
è la velocità di aggiornamento dello schermo
cioè di passaggio dalle immagini nel BackBuffer a quelle
nel FrontBuffer.
hDeviceWindow è il riferimento alla finestra
nella quale viene visualizzata l'immagine. MultiSampleType
è un membro della struttura CONST_D3DMULTISAMPLE_TYPE,
SwapEffect è un membro della struttura CONST_D3DSWAPEFFECT
mentre Windowed indica se l'applicazione è in esecuzione
a tutto schermo (1) oppure in forma di finestra Windows (0)
con la barra del titolo e la barra delle applicazioni.
Adesso,
tornando alla nostra applicazione, dobbiamo includere un bivio:
nel caso in cui l'inizializzazione degli oggetti vada a buon
fine, Inizializza assumerà valore True. In caso contrario
si passerà direttamente alla gestione dell'errore che
assegnerà ad Inizializza il valore False. Per adesso
comunque limitiamoci a rimandare ad un'etichetta generica
chiamata 'Errore' che inseriremo al termine della funzione:
Ora
è tutto pronto per cominciare a creare gli oggetti
che nelle dichiarazioni generali erano stati solo presentati.
Il primo oggetto da creare è una nuova istanza dell'oggetto
principale ossia DirectX:
Come
visto sopra dall'oggetto DirectX vengono creati tutti gli
altri oggetti. Ad esempio possiamo creare una nuova istanza
dell'oggetto Direct3D utilizzando il metodo Direct3DCreate
di DirectX:
Set
D3D = DX.Direct3DCreate() |
E
finalmente siamo pronti a determinare la modalità di
visualizzazione attraverso il metodo GetAdapterDisplayMode
dell'oggetto Direct3D.
I parametri che il metodo richiede sono due: Adapter
che corrisponde alla scheda che gestisce la grafica che può
essere la scheda video primaria (una scheda standard 2D/3D)
o una scheda secondaria che può essere ad esempio una
scheda acceleratrice 3D. La costante che andremo ad indicare,
ossia D3DADAPTER_DEFAULT, rappresenta la scheda video primaria.
Il secondo parametro è DisplayMode, membro della
struttura D3DDISPLAYMODE vista poc'anzi. Avevamo chiamato
tale membro 'Visualizzazione':
D3D.GetAdapterDisplayMode
D3DADAPTER_DEFAULT, Visualizzazione |
Della
struttura D3DPRESENT_PARAMETERS c'interessano tre parametri,
Windowed in modo da settare l'applicazione in una modalità
a tutto schermo, SwapEffect per aggiornare l'immagine
ad una velocità sincronizzata a quella del monitor
e BackBufferFormat al quale assegneremo la modalità
di visualizzazione appena ottenuta utilizzando il metodo GetAdapterDisplayMode:
With
D3DWindow
.Windowed = 1
.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC
.BackBufferFormat = Visualizzazione.Format
End With |
Per
ultimo dobbiamo settare l'oggetto D3DDevice nel seguente modo:
Set
D3DDevice = D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
_
Me.Hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, D3DWindow)
|
dove
D3DADAPTER_DEFAULT indica la scheda video primaria
mentre di quelle secondarie si parlerà solo in un secondo
momento.
D3DDEVTYPE_HAL indica la modalità HAL (Hardware
Accelerator). Me.Hwnd è il parametro indicato da hFocusWindow
e serve alle funzioni per avere un controllo dello stato dell'applicazione
in ogni momento. Indica il riferimento alla finestra nella
quale viene eseguita l'applicazione.
Con D3DCREATE_SOFTWARE_VERTEXPROCESSING si indica il
modo in cui il motore 3D processa le immagini, i vertici,
e le luci. Sebbene sia possibile assegnare tali compiti completamente
alla scheda grafica indicando D3DCREATE_PUREDEVICE,
non tutte le schede supportano questa modalità per
cui è meglio indicare un utilizzo ottimale in base
alle prestazioni della scheda 3D indicando D3DCREATE_SOFTWARE_VERTEXPROCESSING.
Infine con D3DWindow viene presentata la modalità
di visualizzazione che abbiamo assegnato all'oggetto D3DWindow
ossia la modalità a tutto schermo. Per concludere la
funzione d'inizializzazione è necessario impostare
il valore di ritorno e chiudere la funzione:
Inizializza
= True
Exit Function |
In
caso di errore come si è visto prima si va all'etichetta
Errore che assegna il valore False alla funzione:
Errore:
Inizializza = False
End Function |
Ecco
quindi il codice completo di questa applicazione di preparazione,
includendo anche lo svuotamento degli oggetti nella procedura
di chiusura di form1:
Dim
DX As DirectX8
Dim D3D As
Direct3D8
Dim D3DDevice As
Direct3DDevice8
Dim Esecuzione As
Boolean
Private
Sub Form_Load()
Inizializza
End Sub
Private
Function Inizializza() As
Boolean
Dim Visualizzazione As
D3DDISPLAYMODE
Dim D3DWindow As
D3DPRESENT_PARAMETERS
On Error GoTo Errore
Set D3D = DX.Direct3DCreate()
Set D3D = DX.Direct3DCreate()
D3D.GetAdapterDisplayMode D3DADAPTER_DEFAULT, Visualizzazione
With D3DWindow
.Windowed = 1
.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC
.BackBufferFormat = Visualizzazione.Format
End With
Set D3DDevice = D3D.CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, _
Me.Hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, D3DWindow)
Inizializza = True
Exit Function
Errore:
Inizializza = True
End Function |
Adesso
siamo pronti a cominciare nel vero senso della parola. Vedremo
come determinare la risoluzione grafica nel prossimo articolo.
» "DirectX8
Overview" gruppo
Microsoft
» "Getting
started with D3D" di Rod Stephens
» "Meltdown
2000: DirectX8" di Jon Simon & Benjamin Hirsch
|