tutorial - initialize direct3d
create a direct3d project
-
Create a new project: Open Microsoft Visual Studio and create a new empty project of the type "Win32 application". Call
it "dxtut1" and save it in your favorite project location.
-
Add the Direct3D libraries: Go to the settings dialog (Project -> Settings), select "Settings For:
All Configurations". Go to the "Link" tab and add the libraries "d3dx8.lib" and "d3d8.lib"
to the "Object/libary modules" list.
-
Add a new source file: Create a new C++ source file and add it your project. Name it "dxtut1.cpp".
create a window
For this step I won't go into very much detail and will assume that you already know a little bit about
Windows programming. Here we're going to create a simple Windows event loop and put an empty window
up on the screen.
- Copy the following code into dxtut1.cpp:
#include <d3dx8.h>
//-----------------------------------------------------------------------------
// MsgProc
//-----------------------------------------------------------------------------
// Interprets Windows messages
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
case WM_KEYUP:
PostQuitMessage( 0 );
return 0;
case WM_PAINT:
ValidateRect( hWnd, NULL );
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// WinMain
//-----------------------------------------------------------------------------
// Windows main entry point
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"D3D Tutorial 1", NULL };
RegisterClassEx( &wc );
// Create the application's window
HWND hWnd = CreateWindow( "D3D Tutorial 1", "D3D Tutorial 1",
WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
GetDesktopWindow(), NULL, wc.hInstance, NULL );
// Show the window
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );
// Enter the message loop
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message != WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
// Clean up everything and exit the app
UnregisterClass( "D3D Tutorial 1", wc.hInstance );
return 0;
}
- Hit "F5" to compile the code. If you've done everything correctly up until now, everything
should compile and run properly.
create a direct3d device
Once you have a window open you can attach a Direct3D device to the window. For the purpose of this tutorial
we're going to create a simple Direct3D device inside the window we created in the previous step.
- Create global variables to store pointers to our Direct3D device and Direct3D adapter.
At the top of dxtut1.cpp add the following globals:
LPDIRECT3D8 g_pD3D = NULL;
LPDIRECT3DDEVICE8 g_pd3dDevice = NULL;
- Create a Direct3D initialization routine. Add the following function somewhere near the top of
your source file:
//-----------------------------------------------------------------------------
// D3DInit
//-----------------------------------------------------------------------------
HRESULT D3DInit(HWND hWnd)
{
if( NULL == ( g_pD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )
return E_FAIL;
D3DDISPLAYMODE d3ddm;
if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
// We're going to handle lighting ourselves, for now
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
// Turn on the zbuffer
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
return S_OK;
}
This routine takes a pointer to your application's window handle and attaches
a Direct3D software rendering device to it. If you want to create a hardware
rendered window (if your computer supports it) replace D3DDEVTYPE_REF with
D3DDEVTYPE_HAL.
- Create a Direct3D shutdown routine. Copy the following code into your source file:
//-----------------------------------------------------------------------------
// D3DShutdown
//-----------------------------------------------------------------------------
void D3DShutdown()
{
if( g_pd3dDevice != NULL)
g_pd3dDevice->Release();
if( g_pD3D != NULL)
g_pD3D->Release();
}
This routine releases the resources we used.
- Add the D3DInit() and D3DShutdown() functions into your WinMain() function.
// Initialize Direct3D
if( SUCCEEDED( D3DInit(hWnd) ) )
{
// Show the window
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );
// Enter the message loop
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message != WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
}
// Clean up everything and exit the app
D3DShutdown();
UnregisterClass( "D3D Tutorial 1", wc.hInstance );
return 0;
- Verify the code compiles and runs. Notice nothing is drawn in the window (at all)
because we haven't drawn anything yet! :-)
add our rendering routine
In this section we add a simple function that will serve as our primary
rendering function. It will get called everytime Direct3D wants us to draw.
- Create a simple rendering function. Add the following code to your source file:
//-----------------------------------------------------------------------------
// D3DRender
//-----------------------------------------------------------------------------
void D3DRender()
{
if( NULL == g_pd3dDevice )
return;
// Clear the backbuffer to black
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
// Begin the scene
g_pd3dDevice->BeginScene();
// Draw stuff here
// End the scene
g_pd3dDevice->EndScene();
// Present the backbuffer contents to the display
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
This very simple rendering function demonstrates 4 of the 5 steps required to draw
using Direct3D:
- Clear the backbuffer. Before you draw you want to make sure you're starting with a clean
slate.
- Call BeginScene(). This tells Direct3D that you are about to perform drawing.
- Call EndScene(). This tells Direct3D that you are done drawing.
- Call Present(). This tells Direct3D to put your current frame up onto the physical device.
What's the missing step? Drawing, of course. :-)
- Insert your rendering function into the event loop. There are two places you need to do this. The
first is in the MsgProc:
switch( msg )
{
case WM_DESTROY:
case WM_KEYUP:
PostQuitMessage( 0 );
return 0;
case WM_PAINT:
D3DRender();
ValidateRect( hWnd, NULL );
return 0;
}
The second is in WinMain:
// Enter the message loop
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message != WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
D3DRender();
}
- Compile and run your code. You should get a nice black window. :-)
source files
The source file for everything done up until now is available here.
Tutorial Menu
|
|