DirectX初始化
创建D3D对象是进行DirectX编程的第一步,是DirectX程序中第一个创建的对象,也是最后一个释放的对象,在创建D3D对象的过程中需要声明一个指针对象,LPDIRECT3D9 pd3d =NULL,然后对该对象调用Direct3DCreate9函数,函数原型:IDirect3D9 * WINAPI Direct3DCreate9(UINT SDKVersion),改函数的参数一定是D3D_SDK_VERSION,主要功能是检测程序中编辑的头文件与程序运行时调用的DLL是否版本一致,如果不一致则返回NULL指针,Direct3D对象初始化失败,表示程序调用的头文件与程序运行时调用的DLL不匹配,创建Direct3D对象的代码如下:
LPDIRECT3D9 pd3d =NULL; pd3d=Direct3DCreate9(D3D_SDK_VERSION); if(pd3d==NULL) return E_FAIL;
检测硬件设备主要是检测系统中可用显卡的性能,显示模型,格式及其他显卡相关信息。在检测硬件设备中主要检测显卡是否支持硬件顶点运算。
Direct3D设备主要有多种类型,但主要使用的只有2种:HAL设备与REF设备。HAL是D3D编程中的主要设备,它支持硬件加速光栅化以及硬件和软件顶点处理。如果运行的Direct3D程序显卡支持Direct3D,那么Direct3D程序就会使用HAL执行操作,通过硬件来进行坐标变换,光照和光栅化处理,HAL设备速度很快但可能不支持所有的高级功能。
REF设备支持所有的Direct3D特性,并不注重显卡是否对Direct3D特性支持,REF总是通过CPU来进行图形绘制,使用REF来绘制主要是为了测试Direct3D特性,如果想学习Direct3D中的高级特性,而显卡不支持的时候,就可以使用REF来学习Direct3D高级特性,由于HAL没有硬件加速,使用REF来绘制图形速度是比较慢的。
Direct3D支持硬件顶点运算与软件顶点运算,硬件顶点运算就是使用GPU来绘制顶点,软件顶点运算就是使用CPU来绘制顶点。由于GPU与CPU的结构不同,GPU可以容纳上千个没有逻辑关系的数值计算线程,它的优势是无逻辑关系数据的并行计算,因此GPU能够在同一时间里绘制出大量的顶点与三角形,在Direct3D顶点运算中硬件顶点运算的速度是远远高于软件定点运算的速度。检测Direct3D硬件设备的代码如下:
int vp=0;D3DCAPS9 caps; pd3d->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps); if(caps.Caps&D3DDEVCAPS_HWTRANSFORMANDLIGHT) vp=D3DCREATE_HARDWARE_VERTEXPROCESSING; else vp=D3DCREATE_SOFTWARE_VERTEXPROCESSING;
D3DCREATE_HARDWARE_VERTEXPROCESSING是指顶点用硬件来计算,D3DCREATE_SOFTWARE_VERTEXPROCESSIN是指顶点用软件来进行运算。
在硬件检测结束之后就需要对D3DPRESENT_PARAMETERS进行格式填充,改结构定义了Direct3D设备对象的相关信息,这些信息将会影响Direct3D设备的显示方法。先来看看D3DPRESENT_PARAMETERS的相关结构:
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, *LPD3DPRESENT_PARAMETERS;
BackBufferWidth :后台缓冲区的宽,一般就与当前窗口宽度一致。
BackBufferHeight:后台缓冲区的高,一般就与当前窗口搞度一致。
BackBufferFormat:后台缓冲区格式。这个参数是一个D3DFORMAT枚举类型,它的值有很多种,比较常用的有D3DFMT_A8R8G8B8,或者使用D3DFMT_UNKNOWN来代替,这个参数要尤其引起注意,非常容易写错,一旦写错将会导致后面的绘制错误。
BackBufferCount:后备缓冲区数量该值可以从0到3,如果为0,那就当成1来处理,大多数情况我们只使用一个后备缓冲。
MultiSampleType:表示多重采样的类型,一般将此参数设为D3DMULTISAMPLE_NONE,表示不使用多重采样。
MultiSampleQuality :表示多重采样的格式,一般设为0。
SwapEffect:指定Direct3D如何将后台缓冲区的内容复制到前台的缓冲区,通常设为D3DSWAPEFFECT_DISCARD。
hDeviceWindow:窗口句柄。
AutoDepthStencilFormat:表示深度缓冲区与模板缓冲区的格式,通常设为D3DFMT_D24S8。
Windowed:true:如果应用程序运行窗口模式;false:如果应用程序运行的全屏模式。
EnableAutoDepthStencil:如果该值为真,Direct3D会管理的应用深度缓冲区。
Flags:附加参数,通常设为0。
FullScreen_RefreshRateInHz:显示适配器刷新屏幕的刷新率,通常设为D3DPRESENT_RATE_DEFAULT,表示采用默认的刷新频率。
PresentationInterval:表示后台缓冲区与前台缓冲区的最大交换频率,通常设为D3DPRESENT_INTERVAL_IMMEDIATE,表示立刻刷新。下面举一个填充D3DPRESENT_PARAMETERS结构的示例:
D3DPRESENT_PARAMETERS d3dpp; zeroMemory(&d3dpp,sizeof(d3dpp)); d3dpp.BackBufferWidth=640; d3dpp.BackBufferHeight=480; d3dpp.BackBufferFormat=D3DFMT_A8R8G8B8; d3dpp.BackBufferCount=1; d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE; d3dpp.MultiSampleQuality=0; d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow=hwnd; d3dpp.Windowed=true; d3dpp.EnableAutoDepthStencil=true; d3dpp.AutoDepthStencilFormat= D3DFMT_D24S8; d3dpp.Flags=0; d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE;
4 创建D3D设备对象
最后一步就是创建设备,调用第一步创建好的Direct3D接口创建设备对象,来看看创建设备对象的函数CreateDevice。
HRESULT CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DDevice9 **ppReturnedDeviceInterface );
UINT Adapter,表示使用的显卡,一般采用默认显卡D3DADAPTER_DEFAULT。
D3DDEVTYPE DeviceType,表示Direct3D的设备类型,就是第二步使用的数据类型,一般采用D3DDEVTYPE_HAL。
HWND hFocusWindow:当前窗口句柄。
DWORD BehaviorFlags:顶点运算的方式,使用硬件顶点还是软件顶点运算的方式,D3DCREATE_HARDWARE_VERTEXPROCESSING和D3DCREATE_SOFTWARE_VERTEXPROCESSING,或者采用第二步定义好的vp。
D3DPRESENT_PARAMETERS *pPresentationParameters:第三步填充好的D3DPRESENT_PARAMETERS结构。
IDirect3DDevice9 **ppReturnedDeviceInterface:创建好的Direct3D设备接口。
完整的创建方法如下:
LPDIRECT3DDEVICE9 g_pD3DDevice=NULL;
pd3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,vp,&d3dpp,&g_D3DpDevice);
创建好了Direct3D设备接口后就可以利用设备接口来进行图形绘制了,在后面的绘制过程中就是使用g_pD3DDevice来进行绘制,不是使用pD3D对象绘制,这里要区分清楚 LPDIRECT3DDEVICE9与LPDIRECT3D9之间的关系。