下载安装
首先登陆Microsoft Download Center下载最新版本的DirectX SDK。
http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&FamilyID=3021d52b-514e-41d3-ad02-438a3ba730ba
按步骤安装
安装完成后会发现VS2008里面已经设置好相关开发库的目录。
开发D3D程序的一般步骤
D3D对象
在编写D3D程序时,D3D对象是 必须首先创建的对象。通过这个对象,可以去枚举、获取 显示设备所支持的功能。而且这个D3D对象必须最后释放。
通常情况下,我们需要定义一个指针指向所创建的 D3D对象:
LPDIRECT3D9 g_pD3D = NULL;
D3D设备
一个D3D设备接口可以简单的认为是本机一块显卡的抽象,它包含了显卡所有的硬件参数及状态值,比如 说,显卡显存的数量和起始的线性地址,是否支持深度缓冲(Depth Buffer),雾化(Fog),纹理(Texture) 及MipMap等。
通常情况下,也需要定义一个指针指向所创建的3D设备 。如:
// 创建3D程序时需要包含d3d9.h头文件 #include <d3d9.h>
在初始化3D环境之前,需要定义指向3D对象的指针和指向3D设备的指针
// 定义Direct3D对象的指针 LPDIRECT3D9 g_pD3D=NULL; // 定义Direct3D设备指针 LPDIRECT3DDEVICE9 g_pD3dDevice=NULL;
初始化D3D
在创建应用程序窗口后,我们就准备渲染3D场景。在渲染之前,我们必须创建D3D对象和3D设备,因此,可以定义一个Init3D函数,在这个函数里,我们要做的工作:
1.创建3D对象
2.设置present参数
3.创建3D设备
创建3D对象
一个良好的程序编制风格包含了这么一条:任何时候都应该检查函数的返回值,根据函数的返回值决定程序是否应该继续执行下去。
返回诸如:E_FAIL这样的值,而不是返回一个具体的数值,目的是为了和Direct3D系统的返回值统一。便于在Direct3D程序中都可以用SUCCEEDED和FAILED来检查函数调用是成功还是失败。
#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0) #define FAILED(Status) ((HRESULT)(Status)<0)
设置Present参数
在创建3D设备时,创建函数需要知道显示表面的相关参数和信息,所以在创建设备之前,必须设置Present参数。实际上Present参数包含了很多内容,所以在Direct3D中是用一个Present结构来表示的。
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;
常见参数说明:
BackBufferWidth, BackBufferHeight:缓冲区的宽度和高度,如果使用窗口模式,这个值可以随意;如果是全屏模式,则这个值只能是显卡指定的值。
BackBufferCount:缓冲区的个数,可以是0、1、2、3
Windowed:值为TRUE,表示窗口模式,值为FALSE,表示全屏模式
D3DSWAPEFFECT :交换效果
D3DSWAPEFFECT_DISCARD D3DSWAPEFFECT_FLIP
D3DSWAPEFFECT_COPY D3DSWAPEFFECT_COPY_VSYNC
BackBufferFormat:缓冲区的点格式,通常把它设置的和当前桌面的点格式一致。所以则需要用到另一个函数GetAdapterDisplayMode
得到当前显示模式
D3DDISPLAYMODE d3ddm; if (FAILED(g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT,&d3ddm))) { return E_FAIL; }
函数原型:
HRESULT GetAdapterDisplayMode( UINT Adapter, D3DDISPLAYMODE* pMode );
其中参数pMode指向一个D3DDISPLAYMODE 结构体
typedef struct _D3DDISPLAYMODE { UINT Width; UINT Height; UINT RefreshRate; D3DFORMAT Format; } D3DDISPLAYMODE
D3DFORMAT是一个枚举类型,定义了可能的点的格式。
创建Direct3D设备
创建D3D设备需要用到函数CreateDevice,其原型是:
HRESULT IDirect3D9:: CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface ); 参数说明:
Adapter:表示创建的3D设备使用哪块显卡,通常这个值指定为D3DADAPTER_DEFAULT ,表示使用主显示卡
DeviceType:表示创建什么类型的的设备,其中D3DDEVTYPE 是一个枚举类型,定义如下:
typedef enum _D3DDEVTYPE { D3DDEVTYPE_HAL = 1, D3DDEVTYPE_NULLREF = 4, D3DDEVTYPE_REF = 2, D3DDEVTYPE_SW = 3, D3DDEVTYPE_FORCE_DWORD = 0xffffffff } D3DDEVTYPE;
通常情况下,这个参数应该指定为:
D3DDEVTYPE_HAL
hFocusWindow:指示3D设备将场景渲染后,显示的窗口。
BehaviorFlags:这个参数可以取 D3DCREATE_HARDWARE_VERTEXPROCESSING
或D3DCREATE_SOFTWARE_VERTEXPROCESSING
设置3D设备顶点处理的类型的时候,如果可以的话,当然要选用硬件顶点处理,但是由于并非所有显卡都支持硬件顶点处理,因此我们必须首先检查显卡是否支持。我们可以可以使用如下方法 来检查显卡的能力。
HRESULT IDirect3D9::GetDeviceCaps( UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps );
Adapter——指定要获得哪个显示适配器的特性
DeviceType——指定设备类型(硬件设备(D3DDEVTYPE_HAL),软件设备(D3DDEVTYPE_REF))
PCaps——返回一个已初始化的D3DCAPS9结构
然后我们可以用下面的代码段来检查显卡的能力
D3DCAPS9 caps; g_pD3D ->GetDeviceCaps( D3DADAPTER_DEFAULT, // 主显示设备 D3DDEVTYPE_HAL, // 硬件处理的方式 &caps //返回填充后的D3DCAPS9结构,包含主显示设 //备的能力 ); // 下面代码检查计算机系统是否支持硬件顶点处理? int vp = 0; if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) { // 是,支持硬件顶点处理 vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; } else { // 不,只能用软件顶点处理 vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; }
*pPresentationParameters :指向 D3DPRESENT_PARAMETERS结构的指针
ppReturnedDeviceInterface :创建的3D设备的指针
因此创建3D设备的代码段如下:
if (FAILED(g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, vp, &d3dpp, &g_pD3dDevice))) { return E_FAIL; }
渲染
Clear函数:清除颜色、深度缓存、模板缓存
HRESULT Clear( DWORD Count, CONST D3DRECT *pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil );
参数说明:
Count: 要清除的矩形的个数
*pRect: 指向一个矩形数组的首地址,如果该值为NULL,则将整个视口清除
Flags::指定清除那个表面
D3DCLEAR_STENCIL,用Stencil 这个参数的值来清除模板缓存。
D3DCLEAR_TARGET,用指定的颜色清除目标表面。
D3DCLEAR_ZBUFFER,用指定的Z值清除深度缓存。
Color:指定颜色。
Z:指定深度(0.0—1.0)。
Stencil:指定模板缓存的值
resent函数:展现场景
函数原型:
HRESULT Present( CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion );
参数说明:
*pSourceRect:要展现的源矩形表面,一般为NUILL,表示展现整个源表面
*pDestRect:要展现的目标矩形表面,一般可以设为NULL,表示展现到整个窗口或全屏幕式下的这个屏幕
hDestWindowOverride:要展现的目的窗口的句柄,一般为NULL,表示展现到创建Direct3D设备指定的目标窗口
*pDirtyRegion :”脏区域”,一般设为NULL
善后
消息循环结束时,因该释放已创建的3D对象和3D设备
void Cleanup() { if (g_pD3DDevice != NULL) { g_pD3DDevice->Release(); } if (g_pD3D != NULL) { g_pD3D->Release(); } }
在善后时,可以象函数Cleanup那样释放对象,但更经常地做法是使用宏,在文件开头或者在头文件里定义宏:
#define SafeRelease(pObject) / if(pObject != NULL) / {pObject->Release(); / pObject=NULL;}
那么Cleanup函数可以改写为:
void Cleanup() { SafeRelease(g_pD3DDevice); SafeRelease(g_pD3D); }
D3D初始化具体步骤:
创建一个新Win32项目,命名为D3DApp。
选择Windows应用程序的空项目。
添加必要的依赖项,添加需要的静态链接库。
添加一个*.cpp文件。
下面是初始化D3D的完整代码:
源码下载地址:http://download.csdn.net/source/2899387
/* * File : D3DApp.cpp * Description : Create first D3D application * Author : GuoShaoHao * E-mail : [email protected] * Date : 2010/12/06 * * CopyRight @ South China Institute of Software Engineering,.GZU * */ #include <d3d9.h> #include <d3dx9.h> //----------------------------------------------------------------------------- // 全局变量 //----------------------------------------------------------------------------- LPDIRECT3D9 g_pD3D = NULL; // 用于创建D3D设备 LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // 用于创建渲染设备 //----------------------------------------------------------------------------- // Name: InitD3D() // Desc: 初始化D3D //----------------------------------------------------------------------------- HRESULT InitD3D( HWND hWnd ) { // 创建D3D对象 if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL; // 创建结构用于创建D3D设备 D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof( d3dpp ) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; // 创建D3D设备 if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ) { return E_FAIL; } // 设置设备状态 // 设置渲染格式 g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); // 关闭光照 g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); return S_OK; } //----------------------------------------------------------------------------- // Name: InitVB() // Desc: 初始化顶点缓冲 //----------------------------------------------------------------------------- HRESULT InitVB() { return S_OK; } //----------------------------------------------------------------------------- // Name: Cleanup() // Desc: 释放对象资源 //----------------------------------------------------------------------------- VOID Cleanup() { if( g_pd3dDevice != NULL ) g_pd3dDevice->Release(); if( g_pD3D != NULL ) g_pD3D->Release(); } //----------------------------------------------------------------------------- // Name: Render() // Desc: 场景渲染 //----------------------------------------------------------------------------- VOID Render() { // 清除场景背景 g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 ); // 场景开始渲染 if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { // 场景结束渲染 g_pd3dDevice->EndScene(); } // 提交缓冲 g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); } //----------------------------------------------------------------------------- // Name: MsgProc() // Desc: 窗口消息句柄 //----------------------------------------------------------------------------- LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_DESTROY: Cleanup(); PostQuitMessage( 0 ); return 0; } return DefWindowProc( hWnd, msg, wParam, lParam ); } //----------------------------------------------------------------------------- // Name: WinMain() // Desc: 应用程序入口 //----------------------------------------------------------------------------- INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ) { // 注册窗口类 WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "D3D Project", NULL }; RegisterClassEx( &wc ); // 创建应用程序窗口 HWND hWnd = CreateWindow( "D3D Project", "D3D Project", WS_OVERLAPPEDWINDOW, 100, 100, 480, 320, GetDesktopWindow(), NULL, wc.hInstance, NULL ); // 初始化D3D if( SUCCEEDED( InitD3D( hWnd ) ) ) { // 创建顶点缓冲 if( SUCCEEDED( InitVB() ) ) { // 显示窗体 ShowWindow( hWnd, SW_SHOWDEFAULT ); UpdateWindow( hWnd ); // 进入消息循环 MSG msg; ZeroMemory( &msg, sizeof( msg ) ); while( msg.message != WM_QUIT ) { if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { //开始渲染 Render(); } } } } UnregisterClass( "D3D Project", wc.hInstance ); return 0; }