D3D Animation Basis(3)
Initializing Direct3D
Next in line for the helper functions is init_d3d, which you use to initialize Direct3D and create a 3D device and display window. I tried to keep the code as simple as possible, performing the typical initialization code you would use in any Direct3D application.
HRESULT init_d3d(IDirect3D9
**
ret_d3d,
IDirect3DDevice9 ** ret_device,
HWND hwnd,
BOOL force_windowed,
bool multi_threaded)
{
// error checking
if (ret_d3d == NULL || ret_device == NULL || hwnd == NULL)
return E_FAIL;
IDirect3D9 * d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (d3d == NULL)
return E_FAIL;
* ret_d3d = d3d;
// Ask if user wants to run windowed or fullscreen, or force windowed if flagged to do such.
int mode;
if (force_windowed)
mode = IDNO;
else
mode = MessageBox(hwnd, " Use fullscreen mode? (640x480x16) " , " Initialize D3D " , MB_YESNO | MB_ICONQUESTION);
// set the video (depending on windowed mode or fullscreen)
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( & d3dpp, sizeof (d3dpp));
// setup video setttings based on choice of fullscreen or not
if (mode == IDYES) // setup fullscreen format (set to your own if you perfer)
{
// set the presentation parameters (use fullscreen)
d3dpp.BackBufferWidth = 640 ;
d3dpp.BackBufferHeight = 480 ;
d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
d3dpp.Windowed = FALSE;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
}
else // setup windowed format (set to your own demensions below)
{
// get the client and window dimensions
RECT client_rect, window_rect;
GetClientRect(hwnd, & client_rect);
GetWindowRect(hwnd, & window_rect);
// set the width and height (set your dimensions here)
DWORD desired_width = 640 , desired_height = 480 ;
DWORD width = (window_rect.right - window_rect.left) - client_rect.right + desired_width;
DWORD height = (window_rect.bottom - window_rect.top) - client_rect.bottom + desired_height;
// set the window's dimensions
MoveWindow(hwnd, window_rect.left, window_rect.top, width, height, TRUE);
// get the desktop format
D3DDISPLAYMODE display_mode;
d3d -> GetAdapterDisplayMode(D3DADAPTER_DEFAULT, & display_mode);
// set the presentation parameters (use windowed)
d3dpp.BackBufferWidth = desired_width;
d3dpp.BackBufferHeight = desired_height;
d3dpp.BackBufferFormat = display_mode.Format;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = TRUE;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
}
// create the 3D device
DWORD flags = D3DCREATE_MIXED_VERTEXPROCESSING;
if (multi_threaded)
flags |= D3DCREATE_MULTITHREADED;
IDirect3DDevice9 * device;
HRESULT hr = d3d -> CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, flags, & d3dpp, & device);
if (FAILED(hr))
return hr;
// store the 3D device object pointer
* ret_device = device;
// set the perspective projection
float aspect = ( float )d3dpp.BackBufferWidth / d3dpp.BackBufferHeight;
D3DXMATRIX mat_proj;
D3DXMatrixPerspectiveFovLH( & mat_proj, D3DX_PI / 4.0f , aspect, 1.0f , 10000.0f );
device -> SetTransform(D3DTS_PROJECTION, & mat_proj);
// set the default render states
device -> SetRenderState(D3DRS_LIGHTING, FALSE);
device -> SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
device -> SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
device -> SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
// set the default texture stage states
device -> SetTextureStageState( 0 , D3DTSS_COLORARG1, D3DTA_TEXTURE);
device -> SetTextureStageState( 0 , D3DTSS_COLORARG2, D3DTA_DIFFUSE);
device -> SetTextureStageState( 0 , D3DTSS_COLOROP, D3DTOP_MODULATE);
// set the default texture filters
device -> SetSamplerState( 0 , D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
device -> SetSamplerState( 0 , D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
return S_OK;
}
IDirect3DDevice9 ** ret_device,
HWND hwnd,
BOOL force_windowed,
bool multi_threaded)
{
// error checking
if (ret_d3d == NULL || ret_device == NULL || hwnd == NULL)
return E_FAIL;
IDirect3D9 * d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (d3d == NULL)
return E_FAIL;
* ret_d3d = d3d;
// Ask if user wants to run windowed or fullscreen, or force windowed if flagged to do such.
int mode;
if (force_windowed)
mode = IDNO;
else
mode = MessageBox(hwnd, " Use fullscreen mode? (640x480x16) " , " Initialize D3D " , MB_YESNO | MB_ICONQUESTION);
// set the video (depending on windowed mode or fullscreen)
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( & d3dpp, sizeof (d3dpp));
// setup video setttings based on choice of fullscreen or not
if (mode == IDYES) // setup fullscreen format (set to your own if you perfer)
{
// set the presentation parameters (use fullscreen)
d3dpp.BackBufferWidth = 640 ;
d3dpp.BackBufferHeight = 480 ;
d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
d3dpp.Windowed = FALSE;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
}
else // setup windowed format (set to your own demensions below)
{
// get the client and window dimensions
RECT client_rect, window_rect;
GetClientRect(hwnd, & client_rect);
GetWindowRect(hwnd, & window_rect);
// set the width and height (set your dimensions here)
DWORD desired_width = 640 , desired_height = 480 ;
DWORD width = (window_rect.right - window_rect.left) - client_rect.right + desired_width;
DWORD height = (window_rect.bottom - window_rect.top) - client_rect.bottom + desired_height;
// set the window's dimensions
MoveWindow(hwnd, window_rect.left, window_rect.top, width, height, TRUE);
// get the desktop format
D3DDISPLAYMODE display_mode;
d3d -> GetAdapterDisplayMode(D3DADAPTER_DEFAULT, & display_mode);
// set the presentation parameters (use windowed)
d3dpp.BackBufferWidth = desired_width;
d3dpp.BackBufferHeight = desired_height;
d3dpp.BackBufferFormat = display_mode.Format;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = TRUE;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
}
// create the 3D device
DWORD flags = D3DCREATE_MIXED_VERTEXPROCESSING;
if (multi_threaded)
flags |= D3DCREATE_MULTITHREADED;
IDirect3DDevice9 * device;
HRESULT hr = d3d -> CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, flags, & d3dpp, & device);
if (FAILED(hr))
return hr;
// store the 3D device object pointer
* ret_device = device;
// set the perspective projection
float aspect = ( float )d3dpp.BackBufferWidth / d3dpp.BackBufferHeight;
D3DXMATRIX mat_proj;
D3DXMatrixPerspectiveFovLH( & mat_proj, D3DX_PI / 4.0f , aspect, 1.0f , 10000.0f );
device -> SetTransform(D3DTS_PROJECTION, & mat_proj);
// set the default render states
device -> SetRenderState(D3DRS_LIGHTING, FALSE);
device -> SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
device -> SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
device -> SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
// set the default texture stage states
device -> SetTextureStageState( 0 , D3DTSS_COLORARG1, D3DTA_TEXTURE);
device -> SetTextureStageState( 0 , D3DTSS_COLORARG2, D3DTA_DIFFUSE);
device -> SetTextureStageState( 0 , D3DTSS_COLOROP, D3DTOP_MODULATE);
// set the default texture filters
device -> SetSamplerState( 0 , D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
device -> SetSamplerState( 0 , D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
return S_OK;
}