在了解如何初始化Directx3D之前应该首先懂得如何编写一个windows程序,创建一个windwos程序分为4步:1.设计一个窗口类;2.注册一个窗口类;3.创建窗口;4.显示及更新窗口。
以下是创建一个最简单的windows窗口的示例,参考自孙鑫的VC++深入详解.
//-------------------------------------------------------------
//-------------by coderLing
//-------------------------------------------------------------
#include
#include
#include
using namespace std;
//窗口回调函数
LRESULT CALLBACK WinSunProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
//设计一个窗口类
WNDCLASSEX wndcls;
wndcls.cbSize = sizeof(WNDCLASSEX);
wndcls.style = CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = WinSunProc;
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.hInstance = hInstance;
wndcls.hIcon = LoadIcon(NULL,IDI_ERROR);
wndcls.hCursor = LoadCursor(NULL,IDC_CROSS);
wndcls.hbrBackground =
static_cast(GetStockObject(BLACK_BRUSH));
wndcls.lpszClassName = L"CoderLing";
wndcls.lpszMenuName = NULL;
wndcls.hIconSm = 0;
RegisterClassEx(&wndcls);
//创建窗口,定义窗口句柄
HWND hwnd;
hwnd = CreateWindow(L"CoderLing",
L"coderling.com",
WS_OVERLAPPEDWINDOW,
0,
0,
600,
400,
NULL,NULL,hInstance,NULL);
//显示及刷新窗口
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
//定义消息结构体,开始消息循环
MSG msg;
while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return static_cast(msg.wParam);
}
//窗口过程函数
LRESULT CALLBACK WinSunProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
){
switch(uMsg){
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return 0;
}
//
windows程序基于事件消息驱动,上面代码只对WM_DESTROY消息进行了响应,唔。。。这并不是现在的重点,对于这个过程不了解的话,可以去找一本windows程序设计的书看一看,或者留下你的邮箱。重点是WinMain()函数里的消息循环,一般来说对于windows程序是在WIN_PAINT消息触发了才会发生窗口的重绘,但对于一个fps游戏来说我们希望他在没有消息时也应该自动重绘,所以要对这个消息循环进行修改,如下:
MSG msg;
SecureZeroMemory( &msg,sizeof( MSG ) );
while( msg.message != WM_QUIT )
{
if( PeekMessage( &msg,NULL,0U,0U,PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}
好了,现在才是主题,知道了怎去创建一个windows窗口,现在的任务就是在这个基础之上去初始化Directx3D.这里也分为3个要点:1.创建Directx3D对象;2.配置D3DPRESENT_PARAMETERS结构;3.获取Directx3D设备;4.编写渲染函数。
1.第一步很简单,我们通过调用Direct3DCreate9( D3D_SDK_VERSION )
IDirect3D9* d3d9;
d3d9 = Direct3DCreate9(D3D_SDK_VESION);
D3D_SDK_VERSION 是此函数的唯一正确参数。
2.填写D3DPRESENT_PARAMETERS结构,用于获取Directx3D设备。这个结构属性比较多,在这里者填写几个就可以了。
D3DPRESENT_PARAMETERS d3dpp;
SecureZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed = TRUE; //
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; //
3.获取Directx3D设备,通过
HRSULT IDirectx3D::CreateDevice(
UNIT Adapter, //用来创建IDirect3D9设备对象的显卡适配器
D3DDEVICETYPE DeviceType, //设置设备类型,如D3DDEVTYPE_HAL或D3DDEVTYPE_REF
HWND hFocusWindow, //创建的设备对象所绘制的窗口。
DWORD BehaviorFlags, //顶点处理方式,如D3DCREATE_HARDWARE_VERTEXPROCESSING
//或者D3DCREATE_SOFTWARE_VERTEXPROCESSING
D3DPRESENT_PARAMETERS *pPresentationparameters, //填写一个初始化过的D3DPRESENT_PARAMETERS结构
IDirect3DDevice9** ppReturnedDeviceIntface //返回所创建的设备对象。
)
4.最后是编写渲染函数,在这里我们只是把客户区的背景颜色变为蓝色。
VOID Render()
{
if(NULL == g_pd3dDevice)
return ;
//Clear the backbuffer to a blue color.
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0);
//Begin the scene
if(SUCCEEDED( g_pd3dDevice->BeginScene() ))
{
//在此渲染场景里面的对象
g_pd3dDevice->EndScene();
}
//Present the backbuffer contents to the display
g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}
/*---------配置初始化Directx3d---------*/
/*---------by coderLing-----------------/
#include
#define WND_NAME L"D3D"
#define WND_TITLE L"First Direct3DApp"
LPDIRECT3D9 g_pD3D = NULL; //use to create the D3DDevcie
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; //our rendering device
/*---------初始化Direct3d----------*/
HRESULT InitD3D(HWND hWnd)
{
//Create the D3D object,which is neededto create the D3DDevice.
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if(NULL == g_pD3D)
return E_FAIL;
//Set up the structure D3DPRESENT_PARAMETERS
D3DPRESENT_PARAMETERS d3dpp;
SecureZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed = TRUE; //
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; //
//Create the direct3D device.
if( FAILED( g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,&g_pd3dDevice) ) )
{
return E_FAIL;
}
return S_OK;
}
/*------释放所有Direct3d资源------*/
VOID Cleanup()
{
if(NULL != g_pd3dDevice)
g_pd3dDevice->Release();
if(NULL != g_pD3D)
g_pD3D->Release();
}
/*------绘制窗口---------*/
VOID Render()
{
if(NULL == g_pd3dDevice)
return ;
//Clear the backbuffer to a blue color.
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0);
//Begin the scene
if(SUCCEEDED( g_pd3dDevice->BeginScene() ))
{
//在此渲染场景里面的对象
g_pd3dDevice->EndScene();
}
//Present the backbuffer contents to the display
g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}
/*--------消息处理函数------------*/
LRESULT WINAPI MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch( msg )
{
case WM_DESTROY:
Cleanup();
PostQuitMessage( 0 );
return 0;
case WM_PAINT:
Render();
ValidateRect( hWnd, NULL );
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
/*---------主函数----------*/
INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int)
{
//Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,MsgProc,0L,0L,
GetModuleHandle(NULL),NULL,NULL,NULL,NULL,
WND_NAME,NULL};
RegisterClassEx( &wc );
//Create the application window
HWND hWnd = CreateWindow( WND_NAME,WND_TITLE,WS_OVERLAPPEDWINDOW,100,100,300,300,
GetDesktopWindow(),NULL,wc.hInstance,NULL );
if( SUCCEEDED( InitD3D( hWnd ) ) )
{
ShowWindow( hWnd,SW_SHOWDEFAULT );
UpdateWindow( hWnd );
MSG msg;
SecureZeroMemory( &msg,sizeof( MSG ) );
while( msg.message != WM_QUIT )
{
if( PeekMessage( &msg,NULL,0U,0U,PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}
}
UnregisterClass( WND_NAME,wc.hInstance );
}
Step by Step~~~~~~~~~~