[DirectX 9.0笔记]第一章 初始化 Direct3D

时间:2021-09-17 19:45:41

1.Direct3D概述

   

Direct3D的工作框架图如下图所示。

应用程序通过调用Direct3D的API来绘图,Direct3D不直接作用于图形设备,而是通过硬件抽象层(HAL,Hardware Abstraction Layer)操作图形设备。这样的好处是:Direct3D不需要了解图形设备的细节,只要图形设备支持HAL,Direct3D就可以操作该 图形设备。

[DirectX 9.0笔记]第一章 初始化 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++对象。

   

具体说明如下:

  1. 获得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;

}