初始化Direct3D

来源:互联网 发布:一体机电脑推荐知乎 编辑:程序博客网 时间:2024/06/05 09:01

下面几点说明怎样初始化Direct3D。根据下边的步骤你能初始化Direct3D:

1. 获得一个IDirect3D9接口指针。这个接口用于获得物理设备的信息和创建一个IDirect3DDevice9接口,它是一个代表我们显示3D图形的物理设备的C++对象。

2. 检查设备能力(D3DCAPS9),搞清楚主显卡是否支持硬件顶点处理。我们需要知道假如它能支持,我们就能创建IDirect3DDevice9接口。

3. 初始化一个D3DPRESENT_PARAMETERS结构实例,这个结构包含了许多数据成员允许我们指定将要创建的IDirect3DDevice9接口的特性。

4. 创建一个基于已经初始化好的D3DPRESENT_PARAMETERS结构的IDirect3DDevice9对象。它是一个代表我们显示3D图形的物理设备的C++对象。

请注意,本书使用主显示设备绘制3D图形,如果你的机子只有一块显卡,那它就是主显示设备。如果你有多个显卡,那么你当前使用的显卡将会成为主显示设备(如:用来显示Windows桌面的显卡)。

 

1.获得IDirectD9接口

Direct3D的初始化是从获得一个IDirect3D9接口指针开始的。使用一个专门的Direct3D函数来完成这个工作是非常容易的,代码如下:

 

  

IDirect3D9* _d3d9;

 

_d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

Direct3DCreate9的唯一一个参数总是D3D_SDK_VERSION,这可以保证应用程序通过正确的头文件被生成。如果函数调用失败,那么它将返回一个空指针。

IDirect3D9对象通常有两个用途:设备列举和创建IDirect3DDevice9对象。设备列举即为查明系统中显示设备的技术特性,显示模式、格式,以及其它每一种显卡各自支持的特性。创建代表物理设备的IDirect3DDevice9对象,我们需要利用这个物理设备的显示模式结构和格式来创建它。为了找到一个工作配置,我们必须使用IDirect3D9的列举方法。

然而,设备列举实在太慢了,为了使Direct3D运行得尽可能快,我们通常不使用这个测试,除了下一节所谈到的一项测试。为了安全跳过它,我们可以选择总是被所有显卡都支持的“安全”配置。

2 检测硬件顶点处理

当我们创建一个IDirect3DDevice9对象来表示主显示设备时,必须要设定其顶点处理的类型。如果可以的话,当然要选用硬件顶点处理,但是由于并非所有显卡都支持硬件顶点处理,因此我们必须首先检查显卡是否支持。

首先我们要根据主显示设备的技术特性来初始化D3DCAPS9实例。可以使用如下方法:

 

  

HRESULT IDirect3D9::GetDeviceCaps(

 

       UINT Adapter,

 

       D3DDEVTYPE DeviceType,

 

       D3DCAPS9 *pCaps

 

);

 

l  Adapter——指定要获得哪个显示适配器的特性

l  DeviceType——指定设备类型(硬件设备(D3DDEVTYPE_HAL),软件设备(D3DDEVTYPE_REF))

l  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;

 

}

 

观察代码,我们使用变量vp来存储顶点处理类型。这是因为在稍后创建IDirect3DDevice9对象时要求指定其顶点处理的类型。

注意:标识符D3DCREATE_HARDWARE_VERTEXPROCESSING和D3DCREATE_SOFTWARE_VERTEXPROCESSING是预定义的值,它们分别代表硬件顶点处理和软件顶点处理。

 

技巧:若我们开发有一些新的,高级特性的程序,在使用前我们总是先检查硬件是否支持这些特性。

注意:如果一个应用程序在你的机子上不能运行,说明它用到的一些特性可能你的显卡并不支持,可以试试把设备类型换成REF。

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_RefreshRateInHz;

 

       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选择交换速度,通常等于刷新率

填充示例如下:

 

  

D3DPRESENT_PARAMETERS d3dpp;

 

d3dpp.BackBufferWidth = 800;

 

d3dpp.BackBufferHeight = 600;

 

d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; //像素格式

 

d3dpp.BackBufferCount = 1;

 

d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;

 

d3dpp.MultiSampleQuality = 0;

 

d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

 

d3dpp.hDeviceWindow = hwnd;

 

d3dpp.Windowed = false; // fullscreen

 

d3dpp.EnableAutoDepthStencil = true;

 

d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; //  depth format

 

d3dpp.Flags = 0;

 

d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;

 

d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

 

4 创建IDirect3DDevice9对象

在填充完了D3DPRESENT_PARAMETERS结构后,我们就可以用下面的方法创建一个IDirect3DDevice9对象了:

 

  

HRESULT IDirect3D9::CreateDevice(

 

       UINT Adapter,

 

       D3DDEVTYPE DeviceType,

 

       HWND hFocusWindow,

 

       DWORD BehaviorFlags,

 

       D3DPRESENT_PARAMETERS  *pPresentationParameters,

 

       IDirect3DDevice9**  ppReturnedDeviceInterface

 

);

 

l  Adapter——指定对象要表示的物理显示设备

l  DeviceType——设备类型,前面说过

l  hFocusWindow——同我们在前面d3dpp.hDeviceWindow的相同

l  BehaviorFlags——设定为D3DCREATE_SOFTWARE_VERTEXPROCESSING或者D3DCREATE_HARDWARE_VERTEXPROCESSING

l  pPresentationParameters——指定一个已经初始化好的D3DPRESENT_PARAMETERS实例

l  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;

 

}

 

 

 

 

 

原创粉丝点击