1.Direct3D概述
Direct3D的工作框架图如下图所示。
应用程序通过调用Direct3D的API来绘图,Direct3D不直接作用于图形设备,而是通过硬件抽象层(HAL,Hardware Abstraction Layer)操作图形设备。这样的好处是:Direct3D不需要了解图形设备的细节,只要图形设备支持HAL,Direct3D就可以操作该 图形设备。
1 bool supportsHardwareVertexProcessing; 2 // 如果为真,意味着硬件设备支持它 3 if ( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) 4 5 { 6 7 // 支持 8 supportsHardwareVertexProcessing = true; 9 10 } 11 else 12 { 13 // 不支持 14 hardwareSupportsVertexProcessing = false ; 15 }
HAL设备的定义
在代码中,HAL设备用D3DDEVTYPE_HAL来定义。
设备能力
Direct3D支持的每一项特性都对应于D3DCAPS9结构的一个数据成员。我们能够通过监测D3DCAPS9结构中相对应的某一成员来监测设备是否支持这一特性。下面将举例说明,假设我们想要检测显卡是否支持硬件顶点处理(换句话说,就是显卡是否支持硬件几何转换和光源计算)。通过查阅SDK中的D3DCAPS9结构,可以得知数据成员D3DCAPS9::DevCaps中的D3DDEVCAPS _HWTRANSFORMANDLIGHT 位表示硬件是否支持硬件顶点处理即硬件几何变换和光源计算。
// 填充主显示设备的能力(D3DCAPS9结构) D3DCAPS9 caps; d3d9->GetDeviceCaps( D3DADAPTER_DEFAULT, // 主显示设备 deviceType, // 设备类型,一般是D3DDEVTYPE_HAL. &caps); // 返回填充后的D3DCAPS9 结构,包含主显示设备的能力 // 是否可以使用硬件顶点处理? int vp = 0; if ( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) { // 是,支持硬件顶点处理 vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; } else { // 不,只能用软件顶点处理 vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; }
2.初始化Direct3D
步骤:
1.获得一个IDirect3D9接口指针。 这个接口用于获得物理设备的信息和创建一个IDirect3DDevice接口,它是一个代表显示3d图形的物理设备的C++对象。
2.检查设备能力(D3DCAPS9), 搞清楚主显卡是否支持硬件顶点处理。假如它能支持, 我们就能创建IDirect3DDevice9接口。
3.初始化一个D3DPRESENT_PARAMETERS结构实例,这个结构包含了许多数据成员允许我们制定将要创建的IDirect3DDevice9接口的特性。
4.创建一个基于已经初始化好的D3DPRENSENT_PARAMENTS结构的IDirect3DDevice9对象。它是一个代表我们显示3d图形的物理设备的C++对象。
具体说明如下:
-
获得IDirect3D9接口
IDirect3D9* _d3d9;
_d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
Direct3DCreate9 的唯一一个参数总是D3D_SDK_VERSION,这可以保证应用程序通过正确的头文件被生成。如果函数调用失败,那么它将返回一个空指针。
2.监测硬件顶点处理能力
当我们创建一个IDirect3DDevice9对象来表示主显示设备时,必须要设定其顶点处理的类型。如果可以的话,当然要选用硬件顶点处理,但是由于并非所有显卡都支持硬件顶点处理,因此我们必须首先检查显卡是否支持。
首先我们要根据主显示设备的技术特性来初始化D3DCAPS9实例。可以使用如下方法:
HRESULT IDirect3D9::GetDeviceCaps( UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps );
Adapter——指定要获得哪个显示适配器的特性
DeviceType — — 指定设备类型( 硬件设备( D3DDEVTYPE_HAL ),软件设备
(D3DDEVTYPE_REF))
PCaps——返回一个已初始化的D3DCAPS9 结构
然后,我们就可以象1.3.8部分那样检测显卡的能力了。下面就是代码片段:
// 填充主显示设备的能力(D3DCAPS9结构) D3DCAPS9 caps; d3d9->GetDeviceCaps( D3DADAPTER_DEFAULT, // 主显示设备 deviceType, // 设备类型,一般是D3DDEVTYPE_HAL. &caps); // 返回填充后的D3DCAPS9 结构,包含主显示设备的能力 // 是否可以使用硬件顶点处理? int vp = 0; if ( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) { // 是,支持硬件顶点处理 vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; } else { // 不,只能用软件顶点处理 vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; }
3.填充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_Ref reshRateInHz; UINT PresentationInterval; } D3DPRESENT_PARAMETERS;
下面介绍其比较重要的数据成员,至于更详细的信息,请查阅SDK:
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 选择交换速度,通常等于刷新率
4.创建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——返回创建的设备
例子:
IDirect3DDevice9* device = 0; hr = d3d9->CreateDevice( D3DADAPTER_DEFAULT, // primary adapter D3DDEVTYPE_HAL, // device type hwnd, // window associated with device D3DCREATE_HARDWARE_VERTEXPROCESSING, // vertex processing type &d3dpp, // present parameters &device); // returned created device if ( FAILED(hr) ) { ::MessageBox(0, "CreateDevice() - FAILED", 0, 0); return 0; }