DirectX3D初始化四部曲:
- 创建Direct3D接口对象
- 获取设备硬件信息
- 填充D3DPRESENT_PARAMETERS结构体
- 创建Direct3D设备接口
第一步创建接口:
首先定义一个LPDIRECT3D9类型的指针pD3D,接着使用Direct3DCreate9函数初始化该对象。
IDirect3D9 *Direct3DCreate9(
UINT SDKVersion; //表示当前使用的DirectX SDK版本,确保程序与DirectX运行时DLL匹配。
);
LPDIRECT3D9 pD3D = NULL;//Direct3D接口对象的创建
if(NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))//初始化Direct3D接口对象并进行版本协商。
return E_FAIL;
第二部获取设备硬件信息:
在DirectX9中,IDirect3D9接口为我们提供了GetDeviceCaps方法获取设备硬件信息并保存到预设好的D3DCAPS9的结构体当中。
HRESULT GetDeviceCaps(
[in] UINT Adapter, //显卡的序号,通常用D3DADAPTER_DEFAULT,表示使用当前显卡
[in] D3DDEVTYPE DeviceType, //D3DDEVTYPE类型的DeviceType
[out] D3DCAPS9 *pCaps; //D3DCAPS9类型的*pCaps,指向前面的D3DCAPS9结构体
);
typedef enum D3DDEVTYPE{
D3DDEVTYPE_HAL = 1,
D3DDEVTYPE_NULLREF = 4,
D3DDEVTYPE_REF = 2,
D3DDEVTYPE_SW = 3,
D3DDEVTYPE_FOREC_DWORD = 0xffffffff
}D3DDEVTYPE, *LPD3DDEVTYPE;
一般我们只会涉及硬件设备类型D3DDEVTYPE_HAL和软件设备类型D3DDEVTYPE_REF。
在定点运算中应该优先考虑硬件顶点运算,当显卡不支持时再使用软件运算方式:
//创建Direct3D接口对象
LPDIRECT3D9 pD3D = NULL;
if (NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
//获取硬件设备信息
D3DCAPS9 caps;
int vp = 0;
if (FAILED(pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps)))
return E_FAIL;
if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;//支持硬件采用硬件方式
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;//否则采用软件方式
第三部填充结构体:
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.BackBufferWidth = WINDOW_WIDTH; //后台缓冲区宽度
d3dpp.BackBufferHeight = WINDOW_HEIGHT; //后台缓冲区高度
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; //后台缓冲区格式
d3dpp.BackBufferCount = 1; //后台缓冲区数量
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; //多重采样类型
d3dpp.MultiSampleQuality = 0; //多重采样的格式
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //指定Direct3D如何将后台缓冲区的内容复制到前台
d3dpp.hDeviceWindow = hWnd; //窗口句柄
d3dpp.Windowed = true; //显示模式,true表示窗口模式,false为全屏模式
d3dpp.EnableAutoDepthStencil = true; //是否为程序自动管理深度缓存
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; //指定深度缓冲的像素格式,和上一个相关联
d3dpp.Flags = 0; //附加属性,通常为0
d3dpp.FullScreen_RefreshRateInHz = 0; //指定屏幕刷新率,全屏时设为
//D3DPRESENT_RATE_DEFAULT,窗口模式时设为0。
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;//指定前台和后台最大交换频率,可在
//D3DPRESENT中取值。
第四部分创建设备:
if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, vp, &d3dpp, &g_pd3dDevice)))
return E_FAIL;
总体来看:
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
HRESULT Direct3D_Init(HWND hWnd)
{
//创建Direct3D接口对象
LPDIRECT3D9 pD3D = NULL;
if (NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
//获取硬件设备信息
D3DCAPS9 caps;
int vp = 0;
if (FAILED(pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps)))
return E_FAIL;
if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
//第三步 填充D3DPRESENT_PARAMETERS
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.BackBufferWidth = WINDOW_WIDTH;
d3dpp.BackBufferHeight = WINDOW_HEIGHT;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;//多重采样的格式
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.Windowed = true;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = 0;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
//第四步 创建Direct3D设备接口
if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, vp, &d3dpp, &g_pd3dDevice)))
return E_FAIL;
SAFE_RELEASE(pD3D);
if (!(S_OK == Object_Init(hWnd))) return E_FAIL;
return S_OK;
}
本文主要参考浅墨大神的书写的,内容大差不差。