一.DirectX:
DirectX SDK(俗称 Direct X 开发工具包)或者DirectX API(应用程序接口),是一套用于开发高性能多媒体程序的应用程序接口;
DirectX Runtime(DirectX 运行时),是一组动态连接库,是运行利用DirectX SDK开发的程序所必需的动态库。
DirectX SDK包括以下几部分:Direct3D(direct3d,directdraw)、DirectInput、DirectSound、Direct3D简称D3D,集成了开发DirectX程序三维图形部分的所有API 函数,是DirectXDirectMusic、DirectPlay、DirectShow、DirectSetup和DirectX Media Object。
最主要的也是最复杂的一个组件。DirectDraw是用来开发二维图形的一个组件,目前两者合并一起成为Direct Graphics,也称Direct3D.
二.Direct3D体系结构
硬件抽象层(HAL):大多数的Direct3D API设计开发的三维图形程序都运行于硬件抽象层(HAL),即充分利用了硬件系统的加速功能,又隐藏了硬件相关的设备特性,即通过Direct3D实现了硬件无关性。它仅仅是与硬件设备相关的代码,对硬件部支持的功能,不提供软件模拟。提供硬件功能的检查,但不进行参数检查,所有工作要Direct3D在调用HAL之前进行。 硬件
硬件模拟层(HEL)可以在软件中模拟某些特性,现在已不使用。 Direct3D有两种运行模式:窗口模式和全屏模式
WIN32应用程序 -> Dirent3D API -> HAL -> 设备驱动程序接口(DDI) -> 图形
Dirent3D系统集成:
三.在创建Dirent3D设备对象时要先创建Dirent3D对象,Dirent3D的实现方式就是通过组件
对象模型和接口实现的,在使用c++和COM开发方式时可以直接访问这些接口和对象。在使用c++编程时,要先得到一个指向Dirent3D接口的指针,从而通过该指针调用Dirent3D对象的功能。
Dirent3D设备对象(渲染设备),在Dirent3D的渲染组件,在程序中为一个COM对象,它封装和存储了渲染状态。此外还执行坐标变换和光照操作。使用前也需要获取该对象的接口指针。
四.Dirent3D程序基本结构:五大部分包括:
1.创建windows窗口 2.初始化Dirent3D 3.消息循环
4.图形渲染
5.退出Dirent3D程序
1.创建windows窗口
WNDCLASSEX wndclass ; //一个窗口类 wndclass.cbSize = sizeof (wndclass);
//WNDCLASSEX 的大小
wndclass.style = CS_HREDRAW | CS_VREDRAW; //从这个窗口类派生的窗口具有的风格 wndclass.lpfnWndProc = CGameEngine_App::WndProc; //窗口处理函数的指针,回调函数
wndclass.cbClsExtra = 0 ; //指定紧跟在窗口类结构后的附加字节数
wndclass.cbWndExtra = 0 ; //指定紧跟在窗口事例后的附加字节数。如果一个应用程序在资源中用CLASS伪指令注册一个对话框类时,则必须把这个成员设成DLGWINDOWEXTRA wndclass.hInstance = hInstane;//本模块的事例句柄 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); MAKEINTRESOURCE(IDI_DGE) ) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);//光标的句柄
wndclass.hbrBackground =(HBRUSH)GetStockObject(BLACK_BRUSH) ; //背景画刷的句柄
wndclass.lpszMenuName = NULL;
//(wndclass.hInstance,
wndclass.lpszClassName = \
wndclass.hIconSm = LoadIcon(NULL,IDI_APPLICATION); //(wndclass.hInstance, MAKEINTRESOURCE(IDI_DGE) ) ;
// Register the class
RegisterClassEx(&wndclass);
// Create a window
HWND hWnd = CreateWindowEx(
0, // Extended style wndclass.lpszClassName, szTitle,
wndStyle, // Window style 0, // Horizontal origin 0, // Vertical origin
nWidth, nHeight,
//GetSystemMetrics(SM_CXSCREEN), // x size
//GetSystemMetrics(SM_CYSCREEN), // y size // Handle of parent // Handle to menu
NULL, NULL,
wndclass.hInstance,//hInstance,// Application instance NULL); // Additional data
2.初始化Dirent3D,包括Dirent3D对象,Dirent3D设备对象以及要渲染的图形对象
//创建Dirent3D对象 IDirect3D9* m_pDirect3D;
m_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION); //该函数的参数必须是D3D_SDK_VERSION,只有如此方能保证应用程序使用正确的头文件,如果该函数调用失败,将返回一个NULL指针。
//检查渲染设备是否支持所需要的功能 D3DCAPS9 caps;
//用检测到的显示适配器的特性填充D3DCAPS9 结构 m_pDirect3D->GetDeviceCaps(
D3DADAPTER_DEFAULT, //指定物理显卡的序号
D3DDEVTYPE_HAL, //指定设备类型(例如硬件设备(D3DDEVTYPE_HAL)或软件设备&caps );
//返回已初始化的设备性能结构实例
(D3DDEV_TYPE_REF))
int vp = 0;
//检测硬件是否支持变换和灯光
if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
//创建direct3D设备对象
D3DPRESENT_PARAMETERS* m_D3Dpp; //创建Dirent3D设备对象前先对m_D3Dpp进行初始化
ZeroMemory(&m_D3Dpp,sizeof(m_D3Dpp)); //全部置零 m_D3Dpp.BackBufferWidth = m_nWidth;
//后备缓冲的宽度
m_D3Dpp.BackBufferHeight = m_nHeight;//后备缓冲的高度
m_D3Dpp.BackBufferFormat = D3DFMT_A8R8G8B8; //后备缓冲的格式 m_D3Dpp.BackBufferCount = 1; m_D3Dpp.MultiSampleQuality = 0;
//后备缓冲数目
m_D3Dpp.MultiSampleType = D3DMULTISAMPLE_NONE;//全屏抗锯齿类型
//全屏抗锯齿质量等级
交
换
缓
冲
类
型
//设备窗口句柄
//全屏或窗口
m_D3Dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //m_D3Dpp.hDeviceWindow = m_hWindow; m_D3Dpp.Windowed = m_bWindowed; m_D3Dpp.EnableAutoDepthStencil = true; m_D3Dpp.Flags = 0; //显示器刷新率
m_D3Dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //图像最大刷新速度
//
//激活深度缓冲
m_D3Dpp.AutoDepthStencilFormat = D3DFMT_D24S8; //深度缓冲格式 m_D3Dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;
BackBufferWidth和BackBufferHeight:后备缓冲的宽度和高度。在全屏模式下,这两者
的值必需符合显卡所支持的分辨率。例如(800,600),(640,480)。
BackBufferFormat:后备缓冲的格式。这个参数是一个D3DFORMAT枚举类型,它的值有很多种,例如D3DFMT_R5G6B5、D3DFMT_X8R8G8B8为游戏后备缓冲常用格式,这说明后备缓冲的格式是每个像素16位,其实红色(R)占5位,绿色(G)占6位,蓝色(B)占5位,为什么绿色会多一位呢?据说是因为人的眼睛对绿色比较敏感。DX9只支持16位和32位的后备缓冲格式,24位并不支持。如果对这D3DFORMAT不熟悉的话,可以把它设为D3DFMT_UNKNOWN,这时候它将使用桌面的格式。
BackBufferCount:后备缓冲的数目,范围是从0到3,如果为0,那就当成1来处理。
大多数情况我们只使用一个后备缓冲。使用多个后备缓冲可以使画面很流畅,但是却会造成输入设备响应过慢,还会消耗很多内存。
MultiSampleType 和MultiSampleQuality:前者指的是全屏抗锯齿(多重采样)的类型,后者指的是全屏抗锯齿的质量等级。这两个参数可以使你的渲染场景变得更好看,但是却消耗你很多内存资源,而且,并不是所有的显卡都支持这两者的所设定的功能的。在这里我们分别把它们设为D3DMULTISAMPLE_NONE和0。
可以通过CheckDeviceMultiSampleType 来检测当前装置是否支持某个抗锯齿类型 typedef enum _D3DMULTISAMPLE_TYPE {
D3DMULTISAMPLE_NONE = 0, D3DMULTISAMPLE_2_SAMPLES = 2, D3DMULTISAMPLE_3_SAMPLES = 3, D3DMULTISAMPLE_4_SAMPLES = 4, D3DMULTISAMPLE_5_SAMPLES = 5, D3DMULTISAMPLE_6_SAMPLES = 6, D3DMULTISAMPLE_7_SAMPLES = 7, D3DMULTISAMPLE_8_SAMPLES = 8, D3DMULTISAMPLE_9_SAMPLES = 9, D3DMULTISAMPLE_10_SAMPLES = 10, D3DMULTISAMPLE_11_SAMPLES = 11, D3DMULTISAMPLE_12_SAMPLES = 12, D3DMULTISAMPLE_13_SAMPLES = 13, D3DMULTISAMPLE_14_SAMPLES = 14, D3DMULTISAMPLE_15_SAMPLES = 15, D3DMULTISAMPLE_16_SAMPLES = 16, D3DMULTISAMPLE_FORCE_DWORD = 0x7fffffff } D3DMULTISAMPLE_TYPE; // MultiSampleType为以上的枚举值 HRESULT CheckDeviceMultiSampleType(
[in] UINT Adapter,//要查询的显示适配器的序号,D3DADAPTER_DEFAULT始终是主显示适配器
[in] D3DDEVTYPE DeviceType,//顶点处理方式,硬件还是软件? [in] D3DFORMAT SurfaceFormat,// 为后备缓冲格式 [in] BOOL Windowed,// 是否为窗口模式
[in] D3DMULTISAMPLE_TYPE MultiSampleType,
[out]DWORD *pQualityLevels//返回的相对于type的(抗锯齿值)多重采样的最大质量等级 );
SwapEffect:交换缓冲支持的效果类型,指定表面在交换链中是如何被交换的。它是D3DSWAPEFFECT枚举类型,可以设定为以下三者之一:D3DSWAPEFFECT_DISCARD, D3DSWAPEFFECT_FLIP, D3DSWAPEFFECT_COPY。
(1)如果设定为D3DSWAPEFFECT_DISCARD,则后备缓冲区的东西被复制到屏幕上后,后备