一.环境配置
从网上下载到DirectX SDK,双击安装,即可得到以下文件。打开VS2012,打开项目的通用属性,按照图中方法配置库文件以及包含目录。
这样,环境就配置好了。
二.初始化步骤总览
要想使用Direct-X这么强大的功能的图形API,自然要做一番准备工作。具体就分为这么几步: (1) 获得一个IDirect3D9接口指针。这个接口用于获得物理设备的信息和创建一个IDirect3DDevice9接口,它是一个代表我们显示3D图形的物理设备的C++对象。(2) 检查设备的技术特性(D3DCAPS9),搞清楚主显卡是否支持硬件顶点处理。我们需要知道假如它能支持,我们就能创建IDirect3DDevice9接口。
(3)初始化一个D3DPRESENT_PARAMETERS结构实例,这个结构包含了许多数据成员,它们允许我们指定将要创建的IDirect3DDevice9接口的特性。
(4) 创建一个基于已经初始化好的D3DPRESENT_PARAMETERS结构的IDirect3DDevice9对象。它是一个代表我们显示3D图形的物理设备的C++对象。
三.创建Direct3D接口对象
Direct3DCreate9 的唯一一个参数总是D3D_SDK_VERSION,这可以保证应用程序通过正确的头文件被生成。如果函数调用失败,那么它将返回一个空指针。//第一步:创建D3D接口对象
LPDIRECT3D9 pD3D = NULL;//创建接口对象
if (NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))//初始化D3D接口对象,检查SDK版本
return E_FAIL;
四.检查设备信息(是否支持顶点硬件处理)
当我们创建一个IDirect3DDevice9对象来表示主显示设备时,必须要设定其顶点处理的类型。如果可以的话,当然要选用硬件顶点处理,但是由于并非所有显卡都支持硬件顶点处理,因此我们必须首先检查显卡是否支持。通过以下方法检测,原型如下:
HRESULT IDirect3D9::GetDeviceCaps(
UINT Adapter,
D3DDEVTYPE DeviceType,
D3DCAPS9 *pCaps
); 注:
Adapter——指定要获得哪个显示适配器的特性
DeviceType — — 指定设备类型( 硬件设备( D3DDEVTYPE_HAL ), 软件设备(D3DDEVTYPE_REF))
PCaps——返回一个已初始化的D3DCAPS9 结构
例子:
//第二步:获取硬件设备信息
D3DCAPS9 caps;
int vp = 0;
if (FAILED(pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps)))
{
return E_FAIL;
}
if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)//D3DDVCAPS_HWTRANSFORMANDLIGHT表示显卡可以支持变换和光照
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;//如果硬件支持顶点运算,采用硬件顶点运算
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;//不支持硬件顶点运算,采用软件顶点运算
五.填充D3DPRESENT_PARAMETERS 结构
填充一个D3DPRESENT_PARAMETERS 结构的实例。这个结构用于设定我们将要创建的IDirect3DDevice9 对象的一些特性,它的定义如下:
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;
UINT FullScreen_RefreshRateInHz;
UINT PresentationInterval;
} D3DPRESENT_PARAMETERS;
BackBufferWidth——后备缓冲表面的宽度(以像素为单位)
BackBufferHeight——后备缓冲表面的高度(以像素为单位)
BackBufferFormat——后备缓冲表面的像素格式(如:32 位像素格式为D3DFMT——A8R8G8B8)
BackBufferCount——后备缓冲表面的数量,通常设为“1”,即只有一个后备表面
MultiSampleType——全屏抗锯齿的类型,详情请看SDK
MultiSampleQuality——全屏抗锯齿的质量等级,详情看SDK
SwapEffect——指定表面在交换链中是如何被交换的,取D3DSWAPEFFECT 枚举类型中的一个成员。
其中D3DSWAPEFFECT_DISCARD 是最有效的
hDeviceWindow——与设备相关的窗口句柄,你想在哪个窗口绘制就写那个窗口的句柄
Windowed——BOOL 型,设为true 则为窗口模式,false 则为全屏模式
EnableAutoDepthStencil——设为true,D3D 将自动创建深度/模版缓冲
AutoDepthStencilFormat——深度/模版缓冲的格式
Flags——一些附加特性,设为0 或D3DPRESENTFLAG 类型的一个成员。下列两个最常用的标志全部的标志请查阅SDK:
D3DPRESENTFLAG_LOCKABLE_BACKBUFFER——设定后备表面能够被锁定,这会降低应用程序的性能
D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL — — 深度/ 模版缓冲在调用
IDirect3DDevice9::present 方法后将被删除,这有利于提升程序性能
FullScreen_RefreshRateInHz——刷新率,设定D3DPRESENT_RATE_DEFAULT 使用默认刷新率
PresentationInterval——属于D3DPRESENT 成员,又有两个常用标志,其余请查SDK:
D3DPRESENT_INTERVAL_IMMEDIATE——立即交换
D3DPRESENT_INTERVAL_DEFAULT——D3D 选择交换速度,通常等于刷新率
这么多属性,实在是记不住,也没有必要记住,于是摘抄下来,方便查找。 一个填写例子:
//第三步:填写D3DPRESENT_PARAMETERS结构体
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));//清除内容
d3dpp.BackBufferWidth = WINDOW_WIDE;
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;//窗口的句柄(如果设为NULL,就会在当前激活的窗口上绘制)
d3dpp.Windowed = true;//绘制窗体的显示模式,true表示窗口模式,false表示全屏模式
d3dpp.EnableAutoDepthStencil = true;//是否为应用程序自动管理深度缓存
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; //设置深度缓冲的像素格式
d3dpp.Flags = 0;//附加属性,通常为0
d3dpp.FullScreen_RefreshRateInHz = 0;//全屏时屏幕刷新率
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;//后台缓冲区与前台缓冲区最大交换频率
六.创建IDirect3DDevice9 对象
最后一步,通过以下方法就可以创建一个IDirect3DDevice9对象啦。HRESULT IDirect3D9::CreateDevice(UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInterface
);
Adapter——指定对象要表示的物理显示设备
DeviceType——设备类型,前面说过
hFocusWindow——同我们在前面d3dpp.hDeviceWindow 的相同
BehaviorFlags — — 设定为D3DCREATE_SOFTWARE_VERTEXPROCESSING 或者
D3DCREATE_HARDWARE_VERTEXPROCESSING
pPresentationParameters——指定一个已经初始化好的D3DPRESENT_PARAMETERS实例ppReturnedDeviceInterface——返回创建的设备
例子:
//第四步:创建D3D设备接口
if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, vp, &d3dpp, &g_pd3dDevice)))
return E_FAIL;
七.综合Demo
用初始化函数将D3D初始化的四个步骤包含起来HRESULT Init(HWND hWnd)//d3d初始化
{
//第一步:创建D3D接口对象
LPDIRECT3D9 pD3D = NULL;//创建接口对象
if (NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))//初始化D3D接口对象,进行DX版本协商
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)//D3DDVCAPS_HWTRANSFORMANDLIGHT表示显卡可以支持变换和光照
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;//如果硬件支持顶点运算,采用硬件顶点运算
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;//不支持硬件顶点运算,采用软件顶点运算
//第三步:填写D3DPRESENT_PARAMETERS结构体
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));//清除内容
d3dpp.BackBufferWidth = WINDOW_WIDE;
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;//窗口的句柄(如果设为NULL,就会在当前激活的窗口上绘制)
d3dpp.Windowed = true;//绘制窗体的显示模式,true表示窗口模式,false表示全屏模式
d3dpp.EnableAutoDepthStencil = true;//是否为应用程序自动管理深度缓存
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; //设置深度缓冲的像素格式
d3dpp.Flags = 0;//附加属性,通常为0
d3dpp.FullScreen_RefreshRateInHz = 0;//全屏时屏幕刷新率
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;//后台缓冲区与前台缓冲区最大交换频率
//第四步:创建D3D设备接口
if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, vp, &d3dpp, &g_pd3dDevice)))
return E_FAIL;
//释放掉LPDIRECT3D9接口对象
SAFE_RELEASE(pD3D);
}