首先概述一下Direct初始化的大概步骤(稍后我们会详细说明):
1、获取接口IDirect3D9 的指针。该接口用于获取系统物理硬件设备的信息并创建接口:IDirect3DDevice9,接口可以看是一个C++对象,代表了我们用来显示3D图形的硬件物理设备。
2、检查设备的性能(D3DCAPS9),判断显卡是否支持硬件顶点的计算,是因为我们必须明确显卡是否支持该功能,才能创建IDirect3DDevice9接口。
3、初始化一个D3DPRESENT_PARAMETERS结构的实例。该结构由很多的数据成员组成,我们可以通过D3DPRESENT_PARAMETERS里面的变量来决定我们即将创建的IDirect3DDevice9接口的特性。
4、利用已经初始化的结构体D3DPRESENT_PARAMETER创建IDirect3DDevice9对象(一个C++对象,代表我们用来首先是3D图形的物理设备)
注意:我们在学习的阶段可以使用主显卡去绘制我们的图像,如果系统只有一块图形卡,该图形卡就是我们的主显卡。如果本地有多快图形卡,则当前使用的图形卡就是主显卡(当前使用的就是用来显示Windows桌面的那块显卡)。
要初始化Direct3D,就必须获得指向接口IDirect3D9的指针,使用一个专门的Direct3D函数可以很容易的坐到:
IDirect3D9* _d3d9;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
函数Direct3DCreate9的参数必须是D3D_SDK_VERSION,只有如此,才能保证使应用程序使用正确的头文件。如果该函数调用失败,则返回一个NULL指针。
上述的IDirect3D9的对象主要有两个用途:设备枚举以及创建IDirect3DDevice9类型的对象。
设备枚举是指获取系统中可用的每块图形显卡的性能,显示模式,格式以及其他信息。例如:为创建一种代表物理设备的IDirect3DDevice9类型的对象,我们需要知道物理设备所支持的显示模式以及格式等配置信息。为了找到这么一种可行的配置,我们必须使用接口:IDirect3D9的枚举方法。
创建一个主显卡的IDirect3DDevice9类型对象的时候,必须指定使用该对象进行定点运算的类型,也就是是使用硬件顶点运算还是软件顶点运算。如果可以我们尽量使用硬件定点运算,但是不是所有的显卡都支持硬件顶点运算,我们必须先去检查图形卡是否支持该类型的运算。
要进行检查,必须先根据主显卡的性能参数初始化一个IDirect3DDevice9类型的对象,我们用如下方法来进行初始化:
HRESULT IDirect3D9::GetDevice(
UINT Adapter, //指定物理显卡的序号
D3DDEVTYPE DeviceType; //指定设备类型(如硬件设备:D3DDEVTYPE_HAL或者软件设备: D3DDEVTYPE_REF)
D3DCAPS9* pCap //返回已经初始化的设备性能结构实例
)
接下来我们就可以进行设备性能的检查了:
//使用主显示器来填充D3DCAPS9结构体里面的属性
D3DCAPS9 caps;
d3d9->GetDeviceCaps(
D3DADAPTER_DEFAULT, //表示主显示适配器
devicetype, //指定设备类型,通常为D3DDEVTYPE_HAL
&caps //刚我们定义的储存设备信息的结构体的
)
//判断是否可以使用硬件顶点运算
int vp = 0;
if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
{
//如果上述的条件成立,则表示我们可以使用硬件顶点运算,然后我们将硬件顶点运算的类型赋给vp
vp = D3DCREATE_ HARDWARE_VERTEXPROCESSING;
}
else
{
//如果上述的条件不成立,那就把软件顶点运算的类型赋给vp
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
注意:我们将顶点运算的类型赋值给vp保存,以供以后使用,这是因为在创建IDirect3DDevice类型的对象时,必须指定以后所要使用的顶点运算类型。
Direct3D初始化的下一个步骤就是填充一个D3DPRESENT_PARAMETER结构体实例。
该结构用于指定所创建的IDirect3DDevice9类型对象的一些特性,其结构体的定义如下:
typedef struct _D3DPRESENT_PARAMETERS_ {
UINT BackBufferwidth; //后台缓存中表面的宽度,单位为像素
UINT BackBufferHeight; //后台缓存中表面的高度,单位为像素
D3DFORMAT BackBufferFormat; //后台缓存中的像素格式(32位还是16位)
UINT BackBuffercount; //所需使用的后台缓存的个数,通常为1,标明我们仅仅需要一个后台缓存
D3DMULTISAMPLE_TYPE MultiSampleType; //后台缓存所采用的多重采样的类型
DWORD MultiSampleQuality; //多重采样点的质量水平
D3DSWAPEFFECT SwapEffect; //D3DSWAPEFFECT枚举类型的一个成员,该枚举类型指定了交换链中缓存的页面置换方式,当我们设置成:D3DSWAPEFFECT_DISCARD时效率最高
HWND hDevicewindow; //与设备相关的窗口句柄。指定所要绘制的应用程序的窗口
BOOL Windowed; //为true时:窗口模式,为false的时候:为全屏模式
BOOL EnableAutoDepthstencil; //设为true,则Direct3D自动创建并维护深度缓存或模板缓存
D3DFORMAT AutodepthStencilFormat; //深度缓存或者模板缓存的像素格式(例如:24位表示深度并将8位保留模板供模板缓存使用,D3DFMT_D24S8)
DWORD Flags; //下文中参见附带的说明
UINT FullScreen_RefreshRateInHz; //刷新频率,如果想使用默认的刷新频率,可以将此参数设置为:D3DPRESENT_RATE_DEFAULT
UINT PresentationInterval; //提交频率的模式,参看下文中的说明
)D3DPRESENT_PARAMETERS:
参数Flags:
Flags一些附加的特性。可以指定为0(无标记)或D3DPRESENTFLAG集合中的一个成员,其中有两个成员较常用:
·D3DPRESENTFLAG_LOCKABLE_DEPTHBUFFER 指定可锁定的后台缓存。注意,使用个可锁定的后台缓存会降低性能。
·D3DPRESENTFLAG_DISCARD_DEPTHBUFFER 指定当下一个后台缓存提交时,哪个深度或模板缓存将被丢弃(discard)。“丢弃”这个词的意思是深度或模板缓存存储区中的内容被丢弃或无效。这样可以提升性能。
参数PresentationInterval:
·Presentationlnterval D3DPRESENT集合的一个成员。要了解完整的合法时间间隔列表,请参阅相关文档。其中有两个成员较为常用:
·D3DPRESENT_INTERVAL IMMEDIATE 立即提交。
·D3DPRESENT_INTERVAL_DEFAULT 由Direct3D 来选择提交频率(present rate)。通常该值等于刷新频率(refresh rate)。
填充该结构的一个例子如下:
D3DPRESENT_PARAMETERS d3dpp;
d3dpp. BackBufferWidth=800;
d3dpp. BackBufferHeight=600;
d3dpp. BackBufferFormat=D3DFMT_A8R8G8B8;//pixel format
d3dpp. BackBufferCount=1;
d3dpp. MultiSampleType=D3DMULTISAMPLE_NONE;
d3dpp. MultiSampleQuality =0;
d3dpp. SwapEffectD3DSWAPEFFECT_DISCARD;
d3dpp, hDevicewindow=hwnd;
d3dpp. Windowed=false;//fullscreen
d3dpp, EnableAutoDepthstenci1-true;
d3dpp, AutoDepthStenci1Format =D3DFMT_D24s8;//depth format
d3dpp. Flags = 0;
d3dpp. Fu11Screen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp. PresentationIntervel=D3DPRESENT_INTERVAL_IMMEDIATE;
D3DPRESENT_PARAMETERS结构填充完毕之后,我们可以用以下的方法来创建IDirect3DDevice9类型的对象。
HRESULT IDirect3D9::CreatDevice(
UINT Adapter, //指定我们希望用已创建的IDirect3DDevice9对象来代表哪一块显卡
D3DDEVTYPE deviceType, //指定我们需要的设备类型(硬件设备:D3DDEVTYPE_HAL,软件设备:D3DDEVTYPE_REF)
HWND hFocusWindows, //与设备相关的窗口句柄,通常情况下是指设备所需要的进行绘制的目标窗口,为了达到预期的效果,这个句柄应该和D3DPRESENT_PARAMETERS结构的数据成员d3dpp.hDeviceWindow为同一个句柄
DWORD BehaviorFlags, /*该参数可为D3DCREATE_HARDWARE_VERTEXPROCESSING或
D3DCREATE_SOFTWARE_VERTEXPROCESSING*/
D3DPRESENT_PARAMETERS* pPresentationParameters, //一个已经完成初始化的D3DPRESENT_PARAMETERS类型的实例,该实例定义了设备的一些特性。
IDirect3DDevice9** ppReturnedDeviceInterface //返回所创建的设备
)
下面是这个函数的调用实例:
IDirect3DDevice9 * device = 0;
hr = d3d9->CreatDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,
&device
);
if (FAILED(hr))
{
::MessageBox(0,"CreatDevice() - FAILED",0,0);
return 0 ;
}