初学Direct X (1)
Direct3D设备用于访问视频卡的帧缓冲区,以及后台缓冲区。由于IDE是vs2013,默认安装了direct 9,只需要在使用头文件(1)并像使用库文件(2)即可
#include <d3d9.h> ------------(1)
#pragma comment (lib,"d3d9.lib") ------------(2)
1. 关于Direct3D的接口
编写Direct3D程序的第一步,少不了Direct3D的接口变量和图形设备变量,前者的类型是LPDIRECT3D9,后者的类型是LPDIRECT3DDEVICE9,LP意为long pointer,也就是长指针类型,其中
typedef struct IDirect3D9 *LPDIRECT3D9 //LPDIRECT3D9 指向的是 IDirect3D9 *
typedef struct IDirect3DDevice9 *LPDIRECT3DDEVICE9 // LPDIRECT3DDEVICE9 指向的是IDirect3DDevice9 *
在开始的时候直接声明后设置NULL即可:
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
初始化Direct3D:
d3d = Direct3DCreate9(D3D_SDK_VERSION);
创建Direct3D将要输出显示的设备:
d3d->CreateDevice(
UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS* pPresentationParameters, ------------ (3)
IDirect3DDevice9** ppReturnedDeviceInterface ------------ (4)
);
关于后两个参数:
(3):指定设备的参数,假定为d3dpp,这个参数可以自己设定,也可以有动态设置的成分
(4):设备对象,也就是d3ddev
至此,Direct3D初始化就完毕了,接下来整理一下指定设备的参数如何设置
2. 指定设备参数的设置
首先可以看到这个参数类型为D3DPRESENT_PARAMETERS:
typedef struct _D3DPRESENT_PARAMETERS_
{
UINT BackBufferWidth; // 后台缓冲区宽度
UINT BackBufferHeight; // 后台缓冲区高度
D3DFORMAT BackBufferFormat;//后台缓冲区格式
UINT BackBufferCount; // 后台缓冲区数量
D3DMULTISAMPLE_TYPE MultiSampleType;
DWORD MultiSampleQuality;
D3DSWAPEFFECT SwapEffect; // 后台缓冲区的交换模式
HWND hDeviceWindow;
BOOL Windowed; // 是否窗口化
BOOL EnableAutoDepthStencil;
D3DFORMAT AutoDepthStencilFormat;
DWORD Flags;
/* FullScreen_RefreshRateInHz must be zero for Windowed mode */
UINT FullScreen_RefreshRateInHz;
UINT PresentationInterval;
} D3DPRESENT_PARAMETERS;
最后可以进行如下设置:
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp)); //在使用前将结构中的所有值清为零
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = SCREENW;
d3dpp.BackBufferHeight = SCREENH;
d3dpp.hDeviceWindow = hwnd;
另,也有一种灵活的设置方式,可以使得在任意的PC上运行:
// 用于动态获取屏幕信息
D3DDISPLAYMODE dm;
d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&dm);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = dm.Format;//D3DFMT_X8R8G8B8
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = dm.Width;// SCREENW;
d3dpp.BackBufferHeight = dm.Height;// SCREENH;
d3dpp.hDeviceWindow = hwnd;
在我电脑上dm的值为:
Width 1366 unsigned int
Height 768 unsigned int
RefreshRate 60 unsigned int
Format D3DFMT_X8R8G8B8 (22) _D3DFORMAT
3. Game_run()
Direct3D设备创建之后,使用Clear函数来清除后台缓冲区为绿色,这样可以使得在对每一帧进行渲染之前将屏幕清空。
void Game_Run(HWND hwnd) {
if (!d3ddev) return;
//r g b
d3ddev->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,255,0),1.0f,0);
if (d3ddev->BeginScene()) {
// do something
// stop rendering
d3ddev->EndScene();
d3ddev->Present(NULL,NULL,NULL,NULL);//在渲染完成后通过将后台缓冲区复制到视频内存的帧缓冲区中刷新屏幕
}
if (KEY_DOWN(VK_ESCAPE))
PostMessage(hwnd, WM_DESTROY, 0, 0);
}
4.Game_End()
void Game_End(HWND hwnd){
if (d3ddev){
d3ddev->Release();
d3ddev = NULL;
}
if (d3d){
d3d->Release();
d3d = NULL;
}
}