要使用DIRECTX 9有两个很重要的变量DIRECT OBJECT和DIRECT DEVICE:
DIRECT OBJECT提供了一些接口,用这些接口可以知道有哪些设备和设备的信息。
创建DIRECT OBJECT:
IDIRECT3D9 *Direct3DCreate9(D3D_SDK_VERSION);
这里的参数必须为D3D_SDK_VERSION,如果传了错误的版本号码,这个函数将失败,并且返回NULL。
DIRECT DEVICE提供渲染的一些接口。
利用DIRECT OBJECT来创建DIRECT DEVICE:
HRESULT CreateDevice(
UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInterface
);
如果调用成功将返回D3D_OK。
失败会返回D3DERR_INVALIDCALL,某个参数不能用。
D3DERR_NOTAVAILABLE,设备不支持。
D3DERR_OUTOFVIDEOMEMORY,显存不够。
这里面有个比较重要的参数D3DPRESENT_PARAMETERS,它提供了创建设备的一些信息,例如是否全屏,像素格式等等。
结构如下:
typedef struct _D3DPRESENT_PARAMETERS_ {
UINT BackBufferWidth, BackBufferHeight;//缓冲区的宽、高
D3DFORMAT BackBufferFormat;//缓冲区的像素格式,窗口情况下用D3DFMT_UNKNOWN
UINT BackBufferCount;//缓冲区的个数
D3DMULTISAMPLE_TYPE MultiSampleType;
DWORD MultiSampleQuality;
D3DSWAPEFFECT SwapEffect;//缓冲区与前台交换的类型
HWND hDeviceWindow;//与设备绑定的窗口
BOOL Windowed;//是否窗口化
BOOL EnableAutoDepthStencil;
D3DFORMAT AutoDepthStencilFormat;
DWORD Flags;
UINT FullScreen_RefreshRateInHz;
UINT PresentationInterval;
} D3DPRESENT_PARAMETERS;
创建好设备之后,就可以进行渲染了,在绘制每一帧的时候首先要清屏:
HRESULT Clear(
DWORD Count,//要清除的矩形个数,如果是0,则为整个窗口
const D3DRECT* pRects,//要清除的矩阵,Count是0,则该参数必须是NULL
DOWD Flags,//D3DCLEAR_STENCIL,D3DCLEAR_TARGET,D3DCLEAR_ZBUFFER
D3DCOLOR Color,//像素格式
float Z, //深度缓冲值
DWORD Stencil//模板缓冲值
);
当进行了清屏之后就可以进行绘制了,在缓冲区绘制之后,要与前台进行交换,于是就用到了Present函数:
HRESULT Present(
CONST RECT* pSourceRect,//指向缓冲区的某个要进行交换的矩形
CONST RECT* pDestRect,//前台将要用SourceRect进行填充的矩形
HWND hDestWindowOverride,//重绘所操作的窗口,如果使用前面进行绑定的窗口,那么该参数应传入NULL
CONST RGNDATA* pDirtyRegion//脏矩形,可以大大提高效率
);
在进行完渲染之后,要清除不用的设备与接口。
以下是代码:
- #include <Windows.h>
- #include <d3d9.h>
- LPDIRECT3D9 pD3D;
- LPDIRECT3DDEVICE9 pD3DDevice;
- HWND hwnd;
- HRESULT CALLBACK WndProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lParam);
- bool initD3D()
- {
- pD3D=NULL;
- pD3DDevice=NULL;
- if(NULL==(pD3D=Direct3DCreate9(D3D_SDK_VERSION)))
- {
- return false;
- }
- D3DPRESENT_PARAMETERS d3dpp;
- ZeroMemory(&d3dpp,sizeof(d3dpp));
- d3dpp.Windowed=true;
- d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
- d3dpp.BackBufferCount=1;
- d3dpp.BackBufferHeight=768;
- d3dpp.BackBufferWidth=1024;
- d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
- d3dpp.hDeviceWindow=hwnd;
- if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&pD3DDevice)))
- {
- return false;
- }
- return true;
- }
- void render()
- {
- if(NULL==pD3DDevice)
- {
- return;
- }
- pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(255,255,255),1.0f,0);
- pD3DDevice->Present(NULL,NULL,NULL,NULL);
- }
- int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nCmdShow)
- {
- WNDCLASSEX wcex;
- wcex.cbClsExtra=0;
- wcex.cbWndExtra=0;
- wcex.cbSize=sizeof(WNDCLASSEX);
- wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
- wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
- wcex.hIcon=0;
- wcex.hIconSm=0;
- wcex.hInstance=hInstance;
- wcex.lpfnWndProc=(WNDPROC)WndProc;
- wcex.lpszClassName="Directx";
- wcex.lpszMenuName=NULL;
- wcex.style=CS_HREDRAW|CS_VREDRAW;
- RegisterClassEx(&wcex);
- hwnd=CreateWindow("Directx","Directx",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,1024,768,NULL,NULL,hInstance,NULL);
- if(!hwnd)
- {
- return false;
- }
- if(!initD3D())
- {
- return false;
- }
- ShowWindow(hwnd,SW_SHOWNORMAL);
- UpdateWindow(hwnd);
- MSG msg;
- ZeroMemory(&msg,sizeof(msg));
- while(msg.message!=WM_QUIT)
- {
- if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else
- {
- render();
- }
- }
- return (int)msg.wParam;
- }
- HRESULT CALLBACK WndProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lParam)
- {
- switch(umsg)
- {
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- }
- return DefWindowProc(hwnd,umsg,wParam,lParam);
- }
运行之后就可发现一个白色的窗口了。