Direct3D
9 Tutorial
In deze tutorial
ga ik je uitleggen hoe je Direct3D werkt. Direct3D is een onderdeel
van DirectX waarmee je de graphics in je spel/programma regelt. Voor
degene die niet weten wat DirectX is: DirectX is een verzameling DLL's
(gemaakt door Microsoft) die handige en snelle functies bevatten voor
game/multimedia programmeurs. Voor meer informatie over DirectX verwijs
ik je naar www.microsoft.com/directx/

De versie van DirectX
die ik in deze tutorial ga gebruiken in DirectX 9.0. Als je een andere
versie hebt, bv. 8.0 of 8.1 is het ook goed, maar er zitten kleine verschillen
tussen de API's. Voordat je begint moet je eerst de DirectX SDK downloaden.
Als je hem nog niet hebt, klik dan hier om hem te downloaden.
In deze tutorial
zal ik Visual C++ gebruiken. Je kan natuurlijk ook een andere compiler
gebruiken, maar dan zal de code niet gegarandeerd werken. Je kan natuurlijk
altijd vragen stellen in het forum als het niet lukt.
Nadat je de SDK
hebt gedownload, installeer je hem (naar bv. Visual C++ Map\DXSDK\).
Als het goed is worden de include en library directories automatisch
bijgewerkt in VC++. Anders moet je dat handmatig instellen.
Handmatig instellen
(bij VC++.NET, dit kan verschillen bij andere versies):
1. Ga naar "Tools" en het menu en klik op "Options".
2. In de dialoog die nu tevoorschijn komt zie je links een soort mappenlijst.
Klik op de map "Projects".
3. Klik op de sub-map "VC++ Directories".
4. Kies bij "Show directories for: ", "Include files"
5. Klik op de knop met een pictogram van een map om een nieuw adres
toe te voegen waar VC++ moet zoeken voor header files
6. Typ hier Je_SDK_Directory\Include (niet letterlijk natuurlijk)
7. Kies dan bij "Show directories for: ", "Library files".
8. Klik weer op het knopje met een pictogram van een map
9. Typ hier Je_SDK_Directory\Lib
Als het goed is
moet het nu werken.
Maak nu een nieuw
Win32 project aan en voeg d3d9.lib toe aan je libraries. Hierdoor kun
je Direct3D functies gebruiken.
Direct3D initialiseren
Voordat je wat op
het scherm kan zetten, moet je eerst Direct3D initialiseren.
#include <d3d9.h>
// Direct3D header bestand
LPDIRECT3D9 g_pD3D
= NULL; // Pointer naar Direct3D interface
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; // Pointer naar Direct3D device
De g_pD3D variabel
wijst naar de Direct3D interface (IDirect3D9) . LPDIRECT3D9 is getypedeft
als een pointer naar IDirect3D9 en LPDIRECT3DDEVICE9 naar IDirect3DDevice9
(logisch natuurlijk).
Met de Direct3D interface kun je Direct3D initialiseren en vervolgens
een Direct3D device (IDirect3DDevice9) creëren. Bekijk de code hieronder.
BOOL InitDirect3D(HWND
hWnd)
{
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); // Creër Direct3D interface
if(g_pD3D == NULL)
{
return FALSE;
}
...
Met de functie Direct3DCreate9()
creër je de Direct3D interface.
...
D3DPRESENT_PARAMETERS
d3dpp;
ZeroMemory(&d3dpp,
sizeof(d3dpp); // Maak de structure leeg
d3dpp.Windowed = TRUE; // We willen een window, geen volledig scherm
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // Swapeffect
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; // Formaat van de backbuffer
// Creër Direct3D
device
if(FAILED(g_pD3D->CreateDevice(D3D_ADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice);
{
return FALSE;
}
return TRUE;
// Direct3D is klaar voor gebruik
}
De D3DPRESENT_PARAMETERS
structure geeft aan hoe of wat de backbuffer naar de frontbuffer wordt
gekopieerd. De backbuffer is zeg maar een onzichtbaar scherm. Elk frame
dat getekend wordt, wordt eerst opgeslagen in de backbuffer, als het
frame af is, wordt het naar de frontbuffer gekopieerd (ook wel "flippen"
genoemd).
Deze structure heb je nodig in de CreateDevice() functie. Ik zal de
parameters van deze functie even uitleggen. De eerste parameter is de
video adapter (= videokaart). Gebruik hier D3D_ADAPTER_DEFAULT voor
standaard adapter. De tweede parameter is het device type dat je wilt
hebben. Gebruik hier D3DDEVTYPE_HAL om de hardware te gebruiken. De
volgende parameter is gewoon de handle naar je window. In de vierde
parameter geef je met D3DCREATE_SOFTWARE_VERTEXPROCESSING aan dat je
de hardware wil gebruiken voor vertexprocessing (je hoeft niet te weten
wat dit is). De laatste twee parameters is een pointer naar de D3DPRESENT_PARAMETERS
structure en een pointer naar de D3DDevice.
Nu heb je een Direct3D
device. We gaan verder met de Render() functie. In deze tutorial gaan
we nog niks op het scherm tekenen, maar we maken deze functie alvast
voor latere tutorials.
Render
Deze functie wordt
geroepen om een frame te renderen. Als je spel geen window messages
ontvangt oid. kun je een deze functie roepen.
void Render()
{
// Maak het scherm leeg
g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0.0f);
...
Voordat je iets op
het scherm gaat tekenen, moet je eerst het scherm leeg maken (ik noem
het voor het gemak even clearen). Anders wordt het een troepzootje op
je scherm. Dit doe je met de Clear() functie van IDirect3DDevice. In
de clearen. Dat willen we niet, dus we zetten ze op 0 (en de tweede
op NULL, want dat is een pointer), we willen dat het hele scherm gecleared
wordt. De eerste parameter is trouwens de grootte van de array met rechthoeken
dat gecleared moet worden en de tweede parameter het adres daar naartoe.
De derde parameter geeft aan hoe het scherm gecleared moet worden. Zet
hier D3DCLEAR_TARGET neer om het scherm te clearen naar een kleur die
je aangeeft in de volgende parameter. Er zit een handige macro in DirectX
om van RGB waardes een DWORD te maken, namelijk D3DCOLOR_XRGB(rood,
groen, blauw). In deze code wordt het scherm dus groen. De laatste twee
parameters zijn de niet zo belangrijk. Zie MSDN voor verdere informatie.
We zijn nu bij het
belangrijkste deel van je spel: het gedeelte waarmee je iets op het
scherm zet.
...
g_pD3DDevice->BeginScene();
// Begin scene
// Tussen BeginScene
en EndScene kun je teken functies gebruiken
g_pD3DDevice->EndScene();
// End scene
// LET OP: Vergeet
dit niet, met deze functie wordt de inhoud van de
// backbuffer naar de frontbuffer gekopieerd, zodat je iets ziet
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}
Voor deze code is geen verdere uitleg nodig. De parameters bij de Present
functie zijn opties die je later nog kunt gebruiken, maar die heb je
nu nog niet nodig, dus zet ze op NULL.
Clean up, Ruim alles weer netjes op
Aan
het einde van het spel moet je Direct3D uitschakelen. Dit doe je door
de objecten te releasen (loslaten). Je moet dit in dit geval bij twee
objecten doen: Direct3D en Direct3D device.
void CleanUp()
{
if(g_pD3D != NULL) // Controleer of Direct3D wel geinitialiseerd is
g_pD3D->Release(); // Zoja, release hem
if(g_pD3DDevice !=
NULL) // Controleer of er wel een Direct3D device is
g_pD3DDevice->Release(); // Zoja, release hem
}
Je controleert eerst of het object wel geinitialiseerd is, dus of de
pointer niet naar niks wijst (NULL) en daarna release je het object
door object->Release() aan te roepen.
Nu moet je nog een
WinMain functie maken die een window maakt en daarna onze InitDirect3D
functie aanroept. Je hebt ook nog een gameloop functie en een WndProc
nodig. In de gameloop controleer je of er windows messages zijn, zoniet,
render een frame. Als je niet meer precies weet hoe dit moet, bekijk
dan de vorige tutorials dan nog eens.
Golddust
|