DirectX 函数大全


1 网络游戏开发 — DirectXDirectXDirectX DirectX 函数归纳总结 230032300323003 23003 李翔 李 森 2 DirectX DirectX DirectX DirectX 目录 1.D3D 基本框架.................................... 1 创建 D3D 对象.................................................... 2 获取显卡显示模式................................................. 2 创建 D3D 设备接口................................................. 2 开始渲染和结束渲染................................................2 清空图形绘制区................................................... 2 屏幕反转........................................................ 2 2.绘制基本图形.................................... 1 绘制基本图形 ....................................... 4 灵活定点格式(FVF)............................................... 2 基本图元的绘制.................................................... 2 创建顶点缓冲区.................................................... 2 基本图元的绘制.................................................... 2 保存顶点......................................................... 2 设置渲染状态......................................................2 图形绘制......................................................... 2 索引缓冲.......................................... 4 顶点设置.......................................... 2 创建索引缓冲区...................................... 2 保存顶点索引值...................................... 2 索引图形绘制........................................2 D3D 中的图形学...................................... 4 D3D 中的向量........................................2 D3D 中的矩阵........................................2 D3D 中的平面........................................2 3 D3D 中的射线........................................ 2 D3D 中的图形变换...................................... 2 3.纹理 ......................................... 4 从磁盘文件获取纹理.................................................2 设置当前要渲染的纹理............................................... 2 设置纹理的渲染状态.................................... 2 设置纹理采样属性..................................... 2 从一张纹理图形中生成多级纹理.............................. 2 包装纹理寻址......................................................2 镜像纹理寻址......................................................2 夹取纹理寻址......................................................2 边框颜色纹理寻址.................................................. 2 一次镜像纹理寻址.................................................. 2 纹理包装......................................................... 2 4.光照 .......................................... 4 D3D 光照的基本实现.................................... 4 顶点格式.......................................... 2 设置物体材质........................................2 添加光源.......................................... 2 激活光照运算........................................2 5.摄像机 ........................................4 生成视图变换矩阵.................................................. 2 生成投影变换矩阵.................................................. 2 6.模型基础 ...................................... 4 ID3DXMesh 接口基础................................................2 ID3DXMesh 接口相关................................................2 应用.X文件.......................................................2 7.游戏中的基本特效 ............................... 4 4 检查硬件支持的深度缓冲区格式..............................2 激活深度测试........................................2 设置深度缓冲区更新.................................... 2 设置深度测试函数..................................... 2 激活 Alpha 混合......................................2 设置 Alpha 混合计算方式.................................2 设置 Alpha 混合系数................................... 2 激活 Alpha 测试......................................2 设置 Alpha 测试参考值.................................. 2 设置 Alpha 测试函数................................... 2 多边形填充模式...................................... 2 查询设备是否支持多重采样................................ 2 启用多重采样的全景图形反锯齿..............................2 设置多纹理混合方式.................................... 2 激活雾化.......................................... 2 设置雾化计算方式..................................... 2 设置雾的颜色........................................2 设置雾的起始范围..................................... 2 指数雾化浓度........................................2 基于发散的雾化...................................... 2 创建 2D字体........................................ 2 绘制字体.......................................... 2 5 创建 3D文字网格...................................... 2 8.8.8. 8. 游戏控制 ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . 444 4 ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . DirectInput 实现键盘控制 ................................................................ 2 ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . DirectInput 实现鼠标控制 ................................................................ 2 ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . ... . 鼠标键选 ................................................................ 2 9.游戏音乐音效.................................... 4 6 D3D D3D D3D D3D 基本框架 创建D3D D3D D3D D3D 对象: Direct3DCreate9(D3D_SDK_VERSION) ================================================================= ============== DirectX ================================================================= ============== 获取显卡显示模式: HRESULT GetAdapterDisplayMode( UINT Adapter, //指定显示卡序列号 D3DDISPLAYMODE *pMode //存储显示模式的指针 ); ================================================================= ============== DirectX ================================================================= ============== 创建D3DD3DD3D D3D 设备接口: HRESULT CreateDevice( UINT Adapter, //显卡序列号 D3DDEVTYPE DeviceType, //D3D 设备类型 HWND hFocusWindow, //所属窗口句柄 DWORD BehaviorFlags, //设备进行 3D运算 方式 D3DPRESENT_PARAMETERS *pPresentationParameters, //用于存储 D3D 设 备相关信息的指针 IDirect3DDevice9 ** ppReturnedDeviceInterface //返回 D3D 设备接口指针的地址 ); 第二个参数 DeviceType 取值: D3DDEVTYPE_HAL //硬件抽象层,通过显示硬件来完成图形渲染工作 D3DDEVTYPE_REF //参考光栅器,一般用于测试显卡不支持的 D3D 功能 D3DDEVTYPE_SW //用于支持第三方软件 第四个参数 BehaviorFlags 取值: D3DCREATE_SOFTWARE_VERTEXPROCESSING //由D3D 软件进行顶点运算(常用) D3DCREATE_FPU_PRESERVE //激活双精度浮点运算或浮点运算异常 检测,设置该项会降低系统性能 D3DCREATE_MULTITHREADED //保证 D3D 是多线程安全的,设置该项 会降低系统性能 7 D3DCREATE_MIXED_VERTEXPROCESSING //由混合方式进行顶点运算 D3DCREATE_HARDWARE_VERTEXPROCESSING //由D3D 硬件进行顶点运算 D3DCREATE_PUREDEVICE //禁用 D3D 的Get*()函数,禁止 D3D 使用虚拟设备模拟顶点运算 ================================================================= ============== DirectX ================================================================= ============== 开始渲染和结束渲染: BeginScene(); //开始渲染 …… 实际的渲染工作 …… EndScene(); //结束渲染 注意: 这两个函数必须成对出现,不允许交错和嵌套的发生,实际的渲染工作在这两个函数的 中间进行。 ================================================================= ============== DirectX ================================================================= ============== 清空图形绘制区: HRESULT Clear( DWORD Count, //清除的矩形区域数量 const D3DRECT *pRects, //清除的矩形区域数组指针 DWORD Flags, //清除的缓冲区标志,指定清除哪一个缓 冲区 D3DCOLOR Color, //清除后重置的颜色 float Z,//清除后重置的深度值,从 0-1.0 DWORD Stencil //重置的模板值 ); 第三个参数 Flags 取值(可任意组合): D3DCLEAR_STENCIL //模板缓冲区 D3DCLEAR_TARGET //颜色缓冲区 D3DCLEAR_ZBUFFER //深度缓冲区 ================================================================= ============== DirectX ================================================================= ============== 屏幕反转: 8 HRESULT Present( CONSTRECT*pSourceRect, //复制源的矩形区域指针 CONSTRECT*pDestRect, //复制目的地的矩形区域指针 HWND hDestWindowOverride, //D3D 设备窗口句柄 CONSTRGNDATA*pDirtyRegion //最小更新区域指针 ); 注意: 除非 D3D 的交换链是用 D3DSWAPEFFECT_COPY 的标志创建,在大多数的情况下,此 函数的各个参数都设置为 NULL。 ================================================================= ============== DirectX ================================================================= ============== 绘制基本图形 灵活定点格式(FVFFVFFVF FVF ) D3D 定义的 FVF 格式: D3DFVF_XYZ //包含未经变换的顶点坐标 D3DFVF_XYZRHW //包含经过变换的顶点坐标 D3DFVF_XYZW //包含经过变换和裁剪的顶点坐标 D3DFVF_NORMAL //包含法线信息 D3DFVF_PSIZE //点精灵的大小 D3DFVF_DIFFUSE //包含漫反射的颜色信息 D3DFVF_SPECULAR //包含镜面反射的颜色信息 D3DFVF_TEX0……D3DFVF_TEX8 //包含 0-8 个纹理坐标信息 D3DFVF_XYZB1……D3DFVF_XYZB5 //包含顶点位置信息和影响顶点变换的权重信 息,用于骨骼动画模型中 根据 D3D 提供的灵活顶点格式,就可以定义自己的顶点结构体,例如,定义一个包含 经过变换的坐标信息和漫反射颜色信息的顶点结构如下: //创建顶点对象 LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;//顶点缓冲区对象 //自定义顶点格式 struct CUSTOMVERTEX { FLOAT x,y,z,rhw; //经过变换的三维坐标 DWORD color; //顶点漫反射颜色 }; #define D3DFVF_CUSTOMVERTEX(D3DFVF_XYZRHW| D3DFVF_DIFFUSE) //以下函数设置顶点数据 CUSTOMVERTEX vertices[] = { 9 { 100.0f, 400.0f, 0.5f, 1.0f, 0xffff0000, }, { 300.0f, 50.0f, 0.5f, 1.0f, 0xff00ff00, }, { 500.0f, 400.0f, 0.5f, 1.0f, 0xff0000ff, }, }; ================================================================= ============== DirectX ================================================================= ============== 基本图元的绘制 HRESULT ( D3DPRIMITIVETYPE PrimitiveType, //基本图元类型 UINT StartVertex, //起始顶点 UINT PrimitiveCount //绘制图元的数量 ); 第一个参数 PrimitiveType 取值: D3DPT_POINTLIST //点列集合(一组点的集合) D3DPT_LINELIST //线列集合(一组线段的集合) D3DPT_LINESTRIP //线带集合(首尾相连的线段的集合) D3DPT_TRIANGLELIST //三角形列(一组三角形的集合) D3DPT_TRIANGLESTRIP //三角形带 (首尾相连的三角形,有两个顶点重 合) D3DPT_TRIANGLEFAN //三角形扇(组成扇形的一组三角形) ================================================================= ============== DirectX ================================================================= ============== 创建顶点缓冲区 HRESULT CreateVertexBuffer( UINT Length, //顶点缓冲区的大小,按字节数算 DWORD Usage, //顶点缓冲区属性 DWORDFVF,//灵活顶点格式 D3DPOOL Pool, //顶点缓冲区的内存类型 IDirect3DVertexBuffer9** ppVertexBuffer, //顶点缓冲区指针地址 HANDLE* pSharedHandle //保留参数,置为 0 ); *Usage:参数 Usage 用于指定顶点缓冲区的属性,其取值可以设为 0,或下面任意值的组合。 D3DUSAGE_WRITEONLY //只写属性,不能进行读操作,设置该属性可以提高系统性能 D3DUSAGE_DYNAMIC //指定顶点缓冲区要求使用动态内存 D3DUSAGE_NPATCHES //使用顶点缓冲区绘制 N-patches 曲线 D3DUSAGE_POINTS //指定顶点缓冲区存储原始点 D3DUSAGE_RTPATCHES //使用顶点缓冲区绘制高阶图元(high-orderprimitive) 10 D3DUSAGE_SOFTWAREPROCESSING //使用软件进行顶点运算,否则使用硬件计算 *Pool:参数 Pool 属于枚举类型 D3DPOOL,指定顶点缓冲区资源的内存位置,如下: typedef enum _D3DPOOL { D3DPOOL_DEFAULTD3DPOOL_DEFAULTD3DPOOL_DEFAULT D3DPOOL_DEFAULT === = 0,0,0, 0, ////// // 默认值,顶点缓冲区尽可能存在于显存中 D3DPOOL_MANAGEDD3DPOOL_MANAGEDD3DPOOL_MANAGED D3DPOOL_MANAGED === = 1,1,1, 1, ////// // 由D3D D3D D3D D3D 的资源管理器自动调度顶点缓冲 区内存位置 D3DPOOL_SYSTEMMEM = 2, //顶点缓冲区位于内存中 D3DPOOL_SCRATCH = 3, //定点缓冲区位于计算机临时内存中,只能进行内存加锁拷贝 D3DPOOL_FORCE_DWORD = 0x7fffffff //强制将此 ENUM 编译为 32位,无其他意 义 } D3DPOOL; 下面的函数创建了一个顶点缓冲区来保存一个三角形的顶点信息: //创建顶点缓冲 if(FAILED(g_pDevice->CreateVertexBuffer( UINT Length:3*sizeof(CUSTOMVERTEX), DWORD Usage:D3DUSAGE_WRITEONLY, DWORDFVF:D3DFVF_CUSTOMVERTEX, D3DPOOL Pool:D3DPOOL_DEFAULT, ppVertexBuffer:& g_pVB, pSharedHandle:NULL))) { return E_FAIL; } ================================================================= ============== DirectX ================================================================= ============== 保存顶点 HRESULT Lock( UINT OffsetToLock,//加锁内存起始地址 UINT SizeToLock,//加锁内存大小 VOID**ppbData,//返回内存指针地址 DWORD Flags //加锁属性 ); DWORDDWORDDWORD DWORD FlagsFlagsFlags Flags :指定了顶点缓冲区的加锁属性,它可以取值为 0,或者如下中的任意组合: D3DLOCK_DISCARD //仅在动态缓冲区下使用,硬件丢弃原缓冲区并创建一个 新的缓冲区 D3DLOCK_NO_DIRTY_UPDATE //在缺省状态下,对缓冲区加锁将会在该区域设置一个 Dirty 标志,该属性将不对该区域设置 Dirty 标志 D3DLOCK_NOSYSLOCK //在加锁的过程中系统可进行其他操作 D3DLOCK_READONL //设置缓冲区位制度属性 D3DLOCK_NOOVERWRITE //尽在动态缓冲区下使用,保证不覆盖缓冲区数据,即向 11 缓冲区中添加数据,允许在渲染时添加数据到缓冲区 //以下代码保存了顶点 //锁定顶点缓冲 if(FAILED(g_pVertexBuffer->Lock(0,sizeof(Vertices)))) { return E_FAIL; } //拷贝顶点信息 memcpy(g_pVB, vertices,size(vertices)); //解锁 g_pVertexBuffer->Unlock(); ================================================================= ============== DirectX ================================================================= ============== 设置渲染状态 HRESULT SetRenderState( D3DRENDERSTATETYPE State,//需要渲染的状态 DWORD Value //代表设置的渲染状态的值 ); ================================================================= ============== DirectX ================================================================= ============== 图形绘制 *设置资源流 HRESULT SetStreamSource( UINT StreamNumber, //渲染数据流序号 IDirect3DVertexBuffer9 *pStreamData, //进行绑定的顶点缓冲区指针 UINT OffsetInBytes, //进行绑定连接的渲染数据流 的起始位置 UINT Stride //渲染数据流中一个顶点所占的内存的大小 ); *设置顶点格式 HRESULT SetFVF( DWORDFVF//灵活顶点格式 ); *绘制基本图元 HRESULT DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, //绘制的图元类型 12 UINT StartVertex, //绘制的起始顶点 UINT PrimitiveCount //绘制的图元数量 ); // Desc: 渲染图形 VOID Render() { //清空后台缓冲区 g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0 ); //开始在后台缓冲区绘制图形 if(SUCCEEDED( g_pd3dDevice->BeginScene() )) { g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX)); g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );//画 一个三角形 g_pd3dDevice->EndScene();//结束在后台缓冲区绘制图形 } g_pd3dDevice->Present( NULL,NULL,NULL,NULL);//将在后台缓冲区绘 制的图形提交到前台缓冲区显示 } ================================================================= ============== DirectX ================================================================= ============== 索引缓冲 顶点设置 //下面代码片段设置了索引缓冲的值 //----------------------------------------------------------------------------- // Desc: 全局变量 //----------------------------------------------------------------------------- LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;// 顶点缓冲区对象 LPDIRECT3DINDEXBUFFER9 g_pIB = NULL;// 索引缓冲区对象 //----------------------------------------------------------------------------- // Desc: 顶点结构和灵活顶点格式 //----------------------------------------------------------------------------- struct CUSTOMVERTEX {FLOAT x, y, z, rhw; // 经过坐标转换的顶点位置 DWORD color; // 顶点漫反射颜色值 }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE) 13 //----------------------------------------------------------------------------- // Desc: 创建顶点缓冲区和索引缓冲区 //----------------------------------------------------------------------------- HRESULT InitVBAndIB() { //顶点数据 CUSTOMVERTEX g_Vertices[9]; g_Vertices[0].x = 300; g_Vertices[0].y = 250; g_Vertices[0].z = 0.5f; g_Vertices[0].rhw = 1.0f; g_Vertices[0].color = 0xffff0000; for(int i=0; i<8; i++) { g_Vertices[i+1].x = (float)(200*sin(i*3.14159/4.0)) + 300; g_Vertices[i+1].y = -(float)(200*cos(i*3.14159/4.0)) + 250; g_Vertices[i+1].z = 0.5f; g_Vertices[i+1].rhw = 1.0f; g_Vertices[i+1].color = 0xff00ff00; } //顶点索引数组 WORD g_Indices[] ={ 0,1,2, 0,2,3, 0,3,4, 0,4,5, 0,5,6, 0,6,7, 0,7,8, 0,8,1 }; ================================================================= ============== DirectX ================================================================= ============== 创建索引缓冲 HRESULT CreateIndexBuffer( UINT Length, //索引缓冲区大小,按字节数计算 DWORD Usage, //索引缓冲区属性,和顶点缓冲区相同 D3DFORMAT Format, //索引数组的元素格式,可以使 16位或者 32位 D3DPOOL Pool, //索引缓冲区内存位置 IDirect3DIndexBuffer9** ppIndexBuffer, //索引缓冲区指针地址 HANDLE* pSharedHandle //保留参数,设为 0 ); *** * Format:表示索引数组中的元素格式,他可以是 16位整数或者 32位的整数 //创建顶点缓冲区 if(FAILED( g_pd3dDevice->CreateVertexBuffer( 9*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB,NULL ))) { 14 return E_FAIL; } //创建索引缓冲区 if(FAILED( g_pd3dDevice->CreateIndexBuffer( 24*sizeof(WORD), 0, D3DFMT_INDEX16, //索引类型 D3DPOOL_DEFAULT, &g_pIB,NULL ))) { return E_FAIL; } ================================================================= ============== DirectX ================================================================= ============== 保存顶点索引值 //填充顶点缓冲区 VOID* pVertices; if(FAILED( g_pVB->Lock( 0, sizeof(g_Vertices), (void**)&pVertices, 0 ))) return E_FAIL; memcpy( pVertices, g_Vertices, sizeof(g_Vertices) ); g_pVB->Unlock(); //填充索引缓冲区 VOID* pIndices; if(FAILED( g_pIB->Lock( 0, sizeof(g_Indices), (void**)&pIndices, 0 ))) return E_FAIL; memcpy( pIndices, g_Indices, sizeof(g_Indices) ); g_pIB->Unlock(); ================================================================= ============== DirectX ================================================================= ============== 图形绘制 HRESULT SetIndices( IDirect3DIndexBuffer9 *pIndexData //使用的索引缓冲区指针 ); HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, //基本图元类型 INT BaseVertexIndex, //顶点缓冲区的起始位置 UINT MinIndex, //相对于 BaseVertexIndex 的最小索引 UINT NumVertices, //绘制的顶点数目,第一个顶点的位置 UINT StartIndex, //索引缓冲区的起始位置 15 UINT PrimitiveCount //绘制的基本图元数量 ); //----------------------------------------------------------------------------- // 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->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX)); g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); g_pd3dDevice->SetIndices( g_pIB );//设置索引缓冲区 g_pd3dDevice->DrawIndexedPrimitive ( D3DPT_TRIANGLELIST, 0,0,9,0,8 ); //结束在后台缓冲区渲染图形 g_pd3dDevice->EndScene(); } //将在后台缓冲区绘制的图形提交到前台缓冲区显示 g_pd3dDevice->Present( NULL,NULL,NULL,NULL); } ================================================================= ============== DirectX ================================================================= ============== D3D D3D D3D D3D 中的图形学 D3D D3D D3D D3D 中的向量 D3DXVECTOR3 D3DXVECTOR3 D3DXVECTOR3 D3DXVECTOR3 表示三维向量; *** * 向量相等 1.通过“==”来判断向量是否相等,具体如下: D3DXVECTOR3 U(1.0F,0.0F,1.0F); D3DXVECTOR3 v(0.0F,1.0F,0.0F); If(u==v)return true; If(u!=v)return false; 2.判断浮点时应该定义一个“EPSILON”变量,如果两个浮点之间的差距小于 EPSILON 就认为两个浮点数相等,具体如下: const float EPSILON = 0.001f; 16 bool Equals(float 1hs,float rhs) { Return fabs(1hs - rhs)SetMaterial(&mtrl); // m_pD3Ddevice 为有效的 D3D 设备句柄 镜面反射: D3DMATERIAL9 mtrl; ZeroMemory(&mtrl,sizeof(D3DMATERIAL9)); mtrl. Specular.r = 0.8f; mtrl. Specular.g = 0.6f; mtrl. Specular.b = 0.5f; mtrl.Diffuse.a = 0.1f; m_pD3Ddevice->SetMaterial(&mtrl); // m_pD3Ddevice 为有效的 D3D 设备句柄 //进行镜面反射计算时,需要先打开镜面反射的计算,默认情况下镜面反射为关闭 m_pD3Ddevice->SetRenderstate(D3DRS_SPECULARENABLE,TRUE); ================================================================= ============== 25 DirectX ================================================================= ============== 添加光源 光源类型 typedef enum _D3DLIGHTTYPE { D3DLIGHT_POINT = 1, //点光源 D3DLIGHT_SPOT = 2, //聚光灯 D3DLIGHT_DIRECTIONAL = 3, //直射光(或平行光) D3DLIGHT_FORCE_DWORD = 0x7fffffff } D3DLIGHTTYPE; 光源属性 typedef struct _D3DLIGHT9 { D3DLIGHTTYPE Type; //光源类型 D3DCOLORVALUE Diffuse; //光源颜色 D3DCOLORVALUE Specular; D3DCOLORVALUE Ambient; D3DVECTOR Position; //光源位置 D3DVECTOR Direction; //光源方向 float Range; //光源范围 float Falloff; //光源内外锥形衰退 float Attenuation0; //光源衰减系数 float Attenuation1; float Attenuation2; float Theta; //聚光灯内部锥形角度 float Phi; //聚光灯外部锥形角度 } D3DLIGHT9; 设置光源 设置光源时首先定义一个 D3DLIGHT9 D3DLIGHT9 D3DLIGHT9 D3DLIGHT9 类型的结构体,,, , 接下来为对应的光源类型填充其属性,,, , 以下的代码片段定义了 333 3 中类型的光源::: : #define#define#define #define LIGHT_TYPELIGHT_TYPELIGHT_TYPE LIGHT_TYPE 111 1 ////// // 用宏定义说明选择的光源类型 D3DLIGHT9D3DLIGHT9D3DLIGHT9 D3DLIGHT9 d3dLight;d3dLight;d3dLight; d3dLight; MMM M emset(&d3dLight,0,sizeof(d3dlight));emset(&d3dLight,0,sizeof(d3dlight));emset(&d3dLight,0,sizeof(d3dlight)); emset(&d3dLight,0,sizeof(d3dlight)); LightTypeLightTypeLightType LightType === = LIGHT_TYPE;LIGHT_TYPE;LIGHT_TYPE; LIGHT_TYPE; switch(LightType)switch(LightType)switch(LightType) switch(LightType) {{{ { CCC C aseasease ase 1:1:1: 1: ////// // 点光源 BBB B reak;reak;reak; reak; CaseCaseCase Case 2:2:2: 2: ////// // 平行光 BBB B reak;reak;reak; reak; CaseCaseCase Case 3:3:3: 3: ////// // 聚光灯 BBB B reak;reak;reak; reak; }}} } 26 ================================================================= ============== DirectX ================================================================= ============== 激活光照运算 激活光照运算的渲染状态 //m_pDevice 为有效的 D3D 设备句柄 m_Device->SetRenderState(D3DRS_LIGHTING,TRUE); 指定光源 HRESULTHRESULTHRESULT HRESULT SetLightSetLightSetLight SetLight ((( ( DWORDDWORDDWORD DWORD IndexIndexIndex Index ,,, , //取值 0-7 表示设置光源的序号值 CONSTCONSTCONST CONST D3DLIGHT9D3DLIGHT9D3DLIGHT9 D3DLIGHT9 *** * pLightpLightpLight pLight //指向一个表示特定光源的指针 ););); ); // m_pD3Ddevice 为有效的 D3D 设备句柄,d3dLight 为有效的光源指针 m_pD3Ddevice->SetLight(0,&d3dLight); 激活光源 HRESULT LightEnable ( DWORD Index,//指定需要激活的光源的序号值 BOOL Enable //是否激活指定的光源 ); // m_pD3Ddevice 为有效的 D3D 设备句柄,d3dLight 为有效的光源指针 m_pD3Ddevice->SetLight(0,&d3dLight); m_pD3Ddevice->LightEnable(0,TRUE); ================================================================= ============== DirectX ================================================================= ============== 摄像机 生成视图变换矩阵 27 D3DXMATRIX *WINAPI D3DXMatrixLookAtLH( D3DXMATRIX *pOut, //输出用于视图变换的矩阵 CONST D3DXVECTOR3 *pEye, //摄像机的位置 CONST D3DXVECTOR3 *pAt, //视点(摄像机朝向的位置) CONST D3DXVECTOR3 *pUp //摄像机的正方向 ); ================================================================= ============== DirectX ================================================================= ============== 生成投影变换矩阵 D3DXMATRIX *WINAPI D3DXMatrixPerspectiveFovLH( D3DXMATRIX *pOut, //输出用于投影变换的矩阵 FLOAT fovy, //摄像机镜头的夹角(在 Y轴上的成像角度) FLOAT Aspect, //平截台体的纵横比 FLOAT zn, //近平截面的距离 FLOAT zf //远平截面的距离 ); ================================================================= ============== DirectX ================================================================= ============== 28 模型基础 ID3DXMesh ID3DXMesh ID3DXMesh ID3DXMesh 接口基础 几何信息的获取 //获取顶点缓冲 HRESULT ID3DXMesh::GetVertexBuffer(LPDIRECT3DVERTEXBUFFER9* ppVB); //获取索引缓冲 HRESULT ID3DXMesh::GetIndexBuffer(LPDIRECT3DVERTEXBUFFER9* ppVB); 例: //获取顶点缓冲,获取索引缓冲 LPD3DXMESH Mesh; IDirect3DvertexBuffer9* pVB = NULL; IDirect3DvertexBuffer9* pIB = NULL; Mesh-> GetVertexBuffer(&pVB); Mesh-> GetVertexBuffer(&pIB); 填充顶点与索引缓冲 HRESULT ID3DXMesh::LockVertexBuffer( DWORD Flags, //加锁的方式 LPVOID* ppData //返回被锁定的顶点缓冲区指针 ) HRESULT ID3DXMesh::LockIndexBuffer( DWORD Flags, //加锁的方式 LPVOID* ppData //返回被锁定的顶点缓冲区指针 ) HRESULT ID3DXMesh::UnlockVertexBuffer(); //解锁的方式 HRESULT ID3DXMesh::UnlockIndexBuffer(); //解锁的方式 //与Mesh 的几何结构有关的 ID3DXMesh 接口的方法: DWORD GetFVF() -------返回顶点的格式 DWORD GetNumVertices() --------返回顶点缓冲中的顶点数 DWORD GetNumBytesPerVertex() --------返回一个顶点所占的字节数 DWORD GetNumFaces() --------返回 Mesh 的面数,也就是三角形数 子集与属性缓冲 一个 Mesh 由数个子集组成,子集是Mesh 中的一组使用相同属性渲染的三角形,这里 的属性指的是材质,纹理,渲染状态。每一个子集使用唯一的非负整数表示其 ID; 获取属性缓冲 DWORD* buffer = NULL; 29 Mesh->LockAttributeBuffer(lockingFlags,&buffer); //对属性缓冲区进行操作 Mesh->UnlockAttributeBuffer(); 渲染 HRESULT DrawSubset( DWORD AttribId //属性 ID指示 Mesh 中的子集,按照子集的 ID渲染哪 个图形 ); 例: 1.Mesh->DrawSubset(0); 2.for(int i = 0;iSetMaterial(mtrls[i]); Device->SetTexture(0,textures[i]); Mesh->DrawSubset(i); } ================================================================= ============== DirectX ================================================================= ============== ID3DXMesh ID3DXMesh ID3DXMesh ID3DXMesh 接口相关 优化MeshMeshMesh Mesh HRESULT OptimizeInplace( DWORD Flags,//执行优化的类型 CONSTDWORD*pAdjacencyIn,//没有优化的 Mesh 的临接数组 DWORD*pAdjacencyOut,//输出优化的 Mesh 的临接数组 DWORD*pFaceRemap,//接受面重射信息 LPD3DXBUFFER *ppVertexRemap //返回顶点重影射信息 ); 参数 Flags 可取值以下一值或几种值的组合: D3DXMESHOPT_COMPACT //删除没有用的顶点和索引项 D3DXMESHOPT_ATTRSORT //根据属性给三角形排列顺序并调整属性表,这将使 DrawSubset 方法更有效的执行 D3DXMESHOPT_VERTEXCACHE //增加顶点缓冲的命中率 D3DXMESHOPT_STRIPREORDER //重组顶点索引使三角形带尽量长 D3DXMESHOPT_IGNOREVERTS //只优化索引,忽略顶点 注意: D3DXMESHOPT_VERTEXCACHE 和D3DXMESHOPT_STRIPREORDER 不能同时使用; 下面是对一个网格进行优化的片段 DWORD adjacencyInfo[Mesh->GetNumFaces()*3]; Mesh->GenerateAdjacency(0.0f,adjacencyInfo); //用于保存优化的 Mesh 的数组 DWORD optimizedAdjacencyInfo[Mesh->GetNumFaces()*3]; 30 Mesh->OptimizeInplace( D3DXMESHOPT_ATTRSORT| D3DXMESHOPT_COMPACT| D3DXMESHOPT_VERTEXCACHE, adjacencyInfo, optimizedAdjacencyInfo, 0, 0); 还有一种方法是输出一个优化后的 Mesh 而不是在原来的基础上修改; HRESULT Optimize( DWORD Flags,//执行优化的类型 CONSTDWORD*pAdjacencyIn,//没有优化的 MESH 临近数组 DWORD*pAdjacencyOut,//输出优化的 MESH 临近数组 DWORD*pFaceRemap,//接受面重射信息 LPD3DXBUFFER *ppVertexRemap,//返回顶点重影射信息 LPD3DXMESH *ppOptMesh //返回新的网格 ); 属性表 如果一个 MESH 使用D3DXMESHOPT_ATTRSORT 进行优化,那么将创建一个 D3DXATTRIBUTERANGE 结构的属性表数组: typedef struct _D3DXATTRIBUTERANGE { DWORD AttribId; //子集的ID DWORD FaceStart; //该自己的面的起始值 // FaceStart*3就是起始三角形在索引缓冲的序号 DWORD FaceCount; //子集的面数,也就是三角形数 DWORD VertexStart; //该子集的起始顶点在顶点缓冲中的序号 DWORD VertexCount; //该子集包含的顶点数 } D3DXATTRIBUTERANGE; 访问 MESH 的属性表 HRESULT GetAttributeTable( D3DXATTRIBUTERANGE *pAttribTable,//获取属性表的指针 DWORD*pAttribTableSize //属性表的大小,即属性的数量 ); 此方法可以完成两个功能:返回属性表的属性数,返回完整的属性表 返回属性表的元素个数: DWORD num = 0; Mesh->GetAttributeTable(0,&num); //要得到属性表的元素个数可以给第一个参 数传 NULL 然后就可以得到属性表了 D3DXATTRIBUTERANGE table = new D3DXATTRIBUTERANGE[num]; Mesh-> GetAttributeTable(table,&num); 还可以使用 ID3DXMesh::SetAttribute Table 方法直接修改属性表。 31 D3DXATTRIBUTERANGE attributeTable[12]; //填充属性表的值 Mesh->SetAttributeTable(attributeTable,12); ================================================================= ============== DirectX ================================================================= ============== 应用.X.X.X .X 文件 1.1.1. 1. 提取多边形网格信息: HRESULTWINAPI D3DXLoadMeshFromX( LPCTSTR pFilename,//X 文件路径和文件名 DWORD Options,//指定生成多边形网格属性 LPDIRECT3DDEVICE9 pD3DDevice,//D3D 设备指针 LPD3DXBUFFER *ppAdjacency,//存储多边形临接信息 LPD3DXBUFFER *ppMaterials,//存储材质的内存地址 LPD3DXBUFFER *ppEffectInstances,//存储模型特殊效果的内存地址 DWORD*pNumMaterials,//存储材质数目的内存指针 LPD3DXMESH *ppMesh //存储生成的多边形网格的内存地址 ); 下面函数片段从名为 game.x 的文件里读取 3D模型: if( FAILED( D3DXLoadMeshFromX( L"game.x", //X文件名 D3DXMESH_MANAGED, //保存在系统管理内存中 g_pd3dDevice, //D3D设备 NULL,//无需返回临接信息 &pD3DXMtrlBuffer, //返回材质信息 NULL,//无需返回 &g_dwNumMaterials, //返回材质的数目,即MESH的子 集 &g_pMesh //返回的MESH接口对象 ))) { MessageBox(NULL, L"Could not find game.x", L"Mesh", MB_OK); return E_FAIL; } 2.ID3DXBuffer 2.ID3DXBuffer 2.ID3DXBuffer 2.ID3DXBuffer 接口::: : GetBufferPointer(); //返回指向数据块首地址的指针 GetBufferSize();//返回数据块中的大小 注意: ID3DXBuffer ID3DXBuffer ID3DXBuffer ID3DXBuffer 指向的数据块本身是没有数据类型的,所以需要强制转换, 同时 ID3DXBuffer 本身也是一个 COM 对象,所以使用完之后需要调用 Release 方法释放. 例如: D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); pD3DXMtrlBuffer->Release(); 3.载入纹理和材质: 32 typedef struct D3DXMATERIAL { D3DMATERIAL9 MatD3D; //物体的材质信息 LPSTR pTextureFilename; //物体的纹理文件名称 } D3DXMATERIAL; 下面程序片断用于获取 3D模型的材质和纹理信息: //从材质集合中把材质和纹理信息解压读取出来 D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials]; g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials]; 注意:函数 D3DXLoadMeshFromX 调用成功后返回的是一个材质结构体数组,第 i个材质信息 对应的第 i个网格模型的子集,因此可以使用简单的循环来对整个网格进行渲染; for( DWORD i=0; iRelease(); 4.4.4. 4. 绘制网格模型 下面代码片断就是一个网格模型的渲染函数: //逐块渲染网格模型 for( DWORD i=0; iSetMaterial( &g_pMeshMaterials[i] ); g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] ); //渲染模型 g_pMesh->DrawSubset( i ); } ================================================================= ============== DirectX ================================================================= ============== 33 游戏中的基本特效 检查硬件支持的深度缓冲区格式并选择深度缓冲区 HRESULT CheckDeviceFormat( UINT Adapter, //指定显示卡序列号 D3DDEVTYPE DeviceType, //Direct3D 设备类型 D3DFORMAT AdapterFormat, //指定显示模式格式 DWORD Usage, //缓冲区属性 D3DRESOURCETYPE RType, //需要使用查询的格式的设备类型 D3DFORMAT CheckFormat //需要查询的显示格式 ); 深度缓冲区格式: D3DFMT_D32 32位的深度缓冲区 D3DFMT_D15S1 15位的深度缓冲区和 1位的模板缓冲区 D3DFMT_D24S8 32位的深度缓冲区,24 位存储深度值,8位存储模板值 D3DFMT_D24X8 32位的深度缓冲区,24 位存储深度值,8位保留位 D3DFMT_D24X4S4 32位的深度缓冲区,24位存储深度值,4位存储模板值,4位保留位 D3DFMT_D16 16位的深度缓冲区 例如要检测硬件是否支持 32位深度缓冲区,如果支持就选择 32位深度缓冲区: If(m_pD3D- >CheckDeviceFormat(D 3DADAPTER_DEFAULT,D3 DDEVTYPE_HAL,d3ddm.F ormat, D3DUSAGE_DEPTHSTENCIL,D3DRTYPE_SURFACE,D3DFMT_D32 ) ==D3D_OK) { d3dpp.AutoDepthStencilFormat = D3DFMT_D32; d3dpp.EnableAutoDepthStencil = TRUE;//打开深度测试 } ================================================================= 34 ============== DirectX ================================================================= ============== 激活深度测试 g_pDevice->SetRenderState( D3DRS_ZENABLE, TRUE); ================================================================= ============== DirectX ================================================================= ============== 设置深度缓冲区更新 g_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); ================================================================= ============== DirectX ================================================================= ============== 设置深度测试函数 深度测试函数的类型由枚举类型变量 D3DCMPFUNC 决定,其定义如下: typedef enum _D3DCMPFUNC { D3DCMP_NEVER = 1, //深度测试函数总是返回 FALSE D3DCMP_LESS = 2, //测试点深度值小于深度缓冲的值时返回 TRUE D3DCMP_EQUAL = 3, //测试点深度值等于深度缓冲的值时返回 TRUE D3DCMP_LESSEQUAL = 4, //测试点深度值小于等于深度缓冲的值时返回 TRUE D3DCMP_GREATER = 5, //测试点深度值大于深度缓冲的值时返回 TRUE D3DCMP_NOTEQUAL = 6, //测试点深度值不等于深度缓冲的值时返回 TRUE D3DCMP_GREATEREQUAL = 7, //测试点深度值大于等于深度缓冲的值时返回 TRUE D3DCMP_ALWAYS = 8, //深度测试函数总是返回 TRUE D3DCMP_FORCE_DWORD = 0x7fffffff } D3DCMPFUNC; 通常情况下,深度测试函数总是设置为 D3DCMP_LESS: g_pDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESS ); ================================================================= ============== DirectX ================================================================= ============== 激活Alpha Alpha Alpha Alpha 混合 g_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE); ================================================================= 35 ============== DirectX ================================================================= ============== 设置Alpha Alpha Alpha Alpha 混合计算方式 g_pDevice->SetRenderState( D3DRS_BLENDOPALPHA, D3DBLENDOP); D3DBLENDOP 取值: D3DBLENDOP_ADD //源计算结果与颜色缓冲区计算结果相 加 D3DBLENDOP_SUBTRACT //源计算结果减去颜色缓冲区计算结果 D3DBLENDOP_REVSUBTRACT //颜色缓冲区计算结果减去源计算结果 D3DBLENDOP_MIN //取两者的最小值 D3DBLENDOP_MAX //取两者的最大值 ================================================================= ============== DirectX ================================================================= ============== 设置Alpha Alpha Alpha Alpha 混合系数 g_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND); //设置源像 素的 Alpha 混合系数 g_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND); //设置目标 像素的 Alpha 混合系数 D3DBLEND 取值: D3DBLEND_ZERO //Alpha 混合系数为(0,0,0,0) D3DBLEND_ONE //Alpha 混合系数为(1,1,1,1) D3DBLEND_SRCCOLOR //Alpha 混合系数为当前绘制像素的 Color 值(RGBA) D3DBLEND_INVSRCCOLOR //Alpha 混合系数为 1-当前绘制像素的 Color 值(RGBA) D3DBLEND_SRCALPHA //Alpha 混合系数为当前绘制像素的 Alpha 值 D3DBLEND_INVSRCALPHA //Alpha 混合系数为 1-当前绘制像素的 Alpha 值 D3DBLEND_DESTALPHA //Alpha 混合系数为颜色缓冲区中的 Alpha 值 D3DBLEND_INVDESTALPHA //Alpha 混合系数为 1-颜色缓冲区中的 Alpha 值 D3DBLEND_DESTCOLOR //Alpha 混合系数为颜色缓冲区中像素的 Color 值(RGBA) D3DBLEND_INVDESTCOLOR //Alpha 混合系数为 1-颜色缓冲区中像素的 Color 值 (RGBA) ================================================================= ============== DirectX ================================================================= ============== 激活Alpha 测试 g_pDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE); ================================================================= ============== 36 DirectX ================================================================= ============== 设置Alpha 测试参考值 g_pDevice->SetRenderState( D3DRS_ALPHAREF, AlphaReference); AlphaReference 取值范围:0x00000000 ~0x000000ff ================================================================= ============== DirectX ================================================================= ============== 设置Alpha 测试函数 g_pDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMPFUNC); 枚举类型变量 D3DCMPFUNC 取值可参考深度缓冲部分 D3DCMPFUNC 的取值。 ================================================================= ============== DirectX ================================================================= ============== 多边形填充模式((( ( FillmodeFillmodeFillmode Fillmode ))) ) g_pDevice->SetRenderState( D3DRS_FILLMODE, D3DFILLMODE); D3DFILLMODE 取值: D3DFILL_POINT //渲染点模式,Direct3D 在多边形每个顶点绘制一个像素点 D3DFILL_WIREFRAME //渲染线模式,Direct3D 在多边形每个边绘制一条线 D3DFILL_SOLID //渲染面模式,为 Direct3D 默认的填充模式,Direct3D 对 多边形 面进行填充 ================================================================= ============== DirectX ================================================================= ============== 查询设备是否支持多重采样 HRESULT CheckDeviceMultiSampleType( UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels ); 参数 Adapter 表示当前查询的显示硬件的序号,通常以 D3DADAPTER_DEFAULT 表示对 系统当前默认使用的图形显示硬件进行查询。 37 参数 DeviceType 表示当前查询的设备类型,它属于 D3DDEVTYPE 类型。 参数 SurfaceFormat 表示需要查询的渲染表面像素显示格式,它属于 D3DFORMAT 类型。 参数 Windowed 表示是否使用窗口显示。 参数 MultiSampleType 表示需要查询的多重采样方法,它属于 D3DMULTISAMPLE_TYPE 类型 可以指定为 D3DMULTISAMPLE_NONE 来禁用多重采样;或者指定为 D3DMULTISAMPLE_2_SAMPLES 到 D3DMULTISAMPLE_16_SAMPLES 之间的值,来启用 2点采样、3 点采样,直到 16点采样。 参数 pQualityLevels 存储返回的图形质量数值,可设为 NULL,表示无需返回。 ================================================================= ============== DirectX ================================================================= ============== 启用多重采样的全景图形反锯齿 g_pDevice->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, TRUE); ================================================================= ============== DirectX ================================================================= ============== 设置多纹理混合方式 g_pDevice->SetTextureStageState(0 , D3DTSS_COLOROP , D3DTEXTUREOP); 第2个参数取 D3DTSS_COLOROP 或者 D3DTSS_ALPHAOP 来指定纹理 RGB 混合和 Alpha 混合的混合方程式。 参数 D3DTEXTUREOP 取值(Arg1 和Arg2 表示进行混合的两个纹理层的颜色): D3DTOP_DISABLE //禁止纹理混合 D3DTOP_SELECTARG1 //只显示 Arg1 D3DTOP_SELECTARG2 //只显示 Arg2 D3DTOP_MODULATE // Arg1* Arg2 D3DTOP_MODULATE2X // Arg1* Arg2*2 D3DTOP_MODULATE4X // Arg1* Arg2*4 D3DTOP_ADD // Arg1+ Arg2 D3DTOP_ADDSIGNED // Arg1+ Arg2-0.5 D3DTOP_ADDSIGNED2X //( Arg1+ Arg2-0.5)*2 D3DTOP_SUBTRACT // Arg1-Arg2 D3DTOP_ADDSMOOTH // Arg1+ Arg2-Arg1* Arg2 g_pDevice->SetTextureStageState(0 , D3DTSS_COLORARG1, Value); g_pDevice->SetTextureStageState(0 , D3DTSS_COLORARG2, Value); 参数 Value 取值: D3DTA_CURRENT //取前一个纹理层的输出颜色 38 D3DTA_DIFFUSE //取当前像素的漫反射颜色值 D3DTA_TEXTURE //取当前纹理层的颜色值 D3DTA_SPECULAR //取当前像素的镜面反射的颜色 D3DTA_TFACTOR //参数值为 SetRenderState 通过 D3DRS_TEXTUREFACTOR 设置的系数值 D3DTA_SELECTMASK //该状态在设置纹理参数时不起作用 D3DTA_TEMP //取一个临时寄存器中的像素颜色值 D3DTA_CONSTANT //取一个常量作为像素颜色 D3DTA_COMPLEMENT //该参数必须与上一个参数一起设置,表示用 1减去原参数 D3DTA_ALPHAREPLICATE //该参数必须与以上除了 D3DTA_COMPLEMENT 的任意一 个参数同时设置,表示将原参数的 Alpha 值复制到 RGB 中 ================================================================= ============== DirectX ================================================================= ============== 激活雾化 g_pDevice->SetRenderState( D3DRS_FOGENABLE, TRUE); 默认情况下,Direct3D 不激活雾化运算 ================================================================= ============== DirectX ================================================================= ============== 设置雾化计算方式 //设置像素雾化因子的计算方式 g_pDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOGMODE); //设置顶点雾化因子的计算方式 g_pDevice->SetRenderState( D3DRS_FOGVERTEXMODE, D3DFOGMODE); 参数 D3DFOGMODE 取值: D3DFOG_NONE //不计算雾化 D3DFOG_EXP //指数雾化计算 D3DFOG_EXP2 //指数平方雾化计算 D3DFOG_LINEAR //线性雾化计算 D3DFOG_FORCE_DWORD //保留值,没有实际意义 ================================================================= ============== DirectX ================================================================= ============== 设置雾的颜色 g_pDevice->SetRenderState( D3DRS_FOGCOLOR , 0x00ffffff ); Alpha 值对雾没有影响 ================================================================= 39 ============== DirectX ================================================================= ============== 设置雾的起始范围 float start = 50; float end = 500; g_pDevice->SetRenderState( D3DRS_FOGSTART ,*(DWORD*)&start ); g_pDevice->SetRenderState( D3DRS_FOGEND ,*(DWORD*)&end ); 只在线性的雾化时使用。由于 IDirect3DDevice9::SetRenderState()只接受 32位 整数值,所以 设置雾的起始距离和最大距离时需要把他们转换为 DWORD 类型。 ================================================================= ============== DirectX ================================================================= ============== 指数雾化浓度 float density = 0.001f; g_pDevice->SetRenderState( D3DRS_FOGDENSITY ,*(DWORD*)&density); g_pDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_EXP); 浓度值的取值范围从浮点值 0.0~1.0 , 默认为 1.0 。该属性在指数变化的雾化下有效 ================================================================= ============== DirectX ================================================================= ============== 基于发散的雾化 D3DCAPS9 stCaps; g_pDevice->GetDeviceCaps (&stCaps ); if ( stCaps.RasterCaps&D3DPRASTERCAPS_FOGRANGE) { g_pDevice->SetRenderState( D3DRS_RANGEFOGENABLE, TRUE); } 实现基于发散的雾化需要硬件的支持,因此需要首先查询硬件。 ================================================================= ============== DirectX ================================================================= ============== 创建2D2D2D 2D 字体 HRESULTWINAPI D3DXCreateFont( LPDIRECT3DDEVICE9 pDevice, //Direct3D 设备 INT Height, //字体高度 40 UINT Width, //字体宽度 UINT Weight, //字体权重,可以理解为粗体字体的粗细 UINT MipLevels, //多纹理混合的层数 BOOL Italic, //是否斜体(TRUE 表示是斜体) DWORD CharSet, //字体所属字符集 DWORD OutputPrecision, //输出精度,Windows 字体与实际字体 大小对应 DWORD Quality, //字体质量,标明Windows 字体与实际字体对 应 DWORD PitchAndFamily, //字体所属家族 LPCTSTR pFacename, //字体名称 LPD3DXFONT *ppFont //返回一个 ID3DXFont 接口对象 ); 参数 Height 指定创建的字体的高度,取值为 0表示使用系统默认高度,取值为正数表示 含 有内部间隔的字体的高度,取值为负数则以绝对值作为字体的高度。 参数 Width 创建的字体的宽度,通常情况下设为 0,由系统按照字体的高度来选择字体宽 度。 如果要创建点阵字体,则该参数对字体宽度影响很小。 参数 Weight 表示创建的字体的权重,取值在 0~1000 之间,可以表示字体的粗细,例如 , 取值 400 表示正常字体,取值 700 表示 BOLD 字体。 参数 OutputPrecision 指定了 Windows 用实际的字体匹配期望的字体大小和特征的方 式。通 常情况下取值为 OUT_TT_ONLY_PRECIS,表示创建的 TrueType 字体。 参数 Quality 是一个给 Windows 的指令,有关于期望字体与实际字体相匹配的指令。它 实际 只对点阵字体有意义,并不影响 TrueType 字体。通常使用 DEFAULT_QUALITY(0)。 参数 pFacename 指定字样的实际文字名称,可以在 Windows 的字体库中查询到字样名称 , 例如:”Times New Roman”、”Courier”。 下面一段代码用于创建一个简单的宋体字体对象: D3DXCreateFont(g_pd3dDevice,0,0,400,0,false,ANSI_CHARSET,OUT_TT_O NLY_PRECIS, DEFAULT_QUALITY, 0, "宋体",&g_pFont); ================================================================= ============== DirectX ================================================================= ============== 绘制字体 INT DrawText( LPD3DXSPRITE pSprite, //指定字符串所属的 ID3DXSPrite 对象接 口。可以取 NULL LPCTSTR pString, //指定用于显示的字符串 41 INT Count, //显示的文本字符串中字符的数量,如果为-1则 绘制到字符串结尾 LPRECT pRect, //字符串绘制的位置 DWORD Format, //字符串格式化属性 D3DCOLOR Color //字符串颜色 ); 参数 Format 取值: DT_BOTTOM//字符串位于 rect 底部,与 DT_SINGLELINE 共存 DT_CALCRECT//根据字符串长度改变矩形区域大小 DT_CENTER//字符串水平居中 DT_LEFT//字符串左对齐 DT_NOCLIP//不对字符串进行裁剪 DT_RIGHT//字符串右对齐 DT_SINGLELINE//单行显示 DT_TOP//字符串位于矩形区域顶部 DT_VCENTER//字符串位于矩形区域垂直居中 ================================================================= ============== DirectX ================================================================= ============== 创建3D3D3D 3D 文字网格 HRESULTWINAPI D3DXCreateText( LPDIRECT3DDEVICE9 pDevice, //Direct3D 设备 HDC hDC, //描述字体的 Windows 设备句柄 LPCTSTR pText, //显示的文字 FLOAT Deviation, //最大字型弦长偏差,通常设为 0 FLOAT Extrusion, //文字在 z轴方向的深度 LPD3DXMESH *ppMesh, //返回的 3D文字网格 LPD3DXBUFFER *ppAdjacency, //返回创建的 3D文字网格相关信息,可 为NULL LPGLYPHMETRICSFLOAT pGlyphMetrics// 一 个 指 向 GLYPHMETRICSFLOAT 结构的指针, 描述字型的相关信息,通常为 0 ); ================================================================= ============== DirectX ================================================================= ============== 实现游戏控制 DirectInput DirectInput DirectInput DirectInput 实现键盘控制 42 创建 DirectInput 对象: HRESULTWINAPI DirectInput8Create( HINSTANCE hinst,//windows 进程句柄 DWORD dwVersion,//版本通常取 DIRECTINPUT_VERSION REFIID riidltf,//接口的标识,通常取 IID_IdirectInput8 LPVOID*ppvOut,//返回的 DirectInput 对象指针 LPUNKNOWN punkOuter //COM 对象指针,一般取 NULL ); LPDIRECTINPUT8 m_pDInput; if (DI_OK!=DirectInput8Create(hInst,DIRECTINPUT_VERSION, IID_IDirectInput8,(LPVOID*)&m_pDInput,NULL)) { MessageBox(hWnd,"创建DInput对象失败!","ERROR",MB_OK); } 创建设备对象: HRESULTIdirectInput8::CreateDevice( REFGUID rguid, //设备标识 LPDIRECTINPUTDEVICE*lplpDirectInputDevice, //DirectInput 设备对象 LPUNKNOWN pUnkOuter //COM 对象 ); LPDIRECTINPUTDEVICE8 m_pKeyboard; //创建键盘设备 if (DI_OK!=M_PdiNPUT->cREATEdEVICE(guid_SysKeyboard,&m_pKeyboard,NULL)) { MessageBox(HWND,"创建键盘设备失败!","ERROR",MB_ICONERROR|MB_OK); } 1.设置键盘设备状态: HRESULT IDirectInputDevice8::SetDataFormat( LPCDIDATAFORMAT lpdf //数据格式 );  参数 lpdf 可选择为:  c_dfDIKeyboard //标准键盘对象  c_dfDIMouse //标准鼠标对象  c_dfDIMouse2 //标准鼠标对象  c_dfDIJoystick //标准游戏杆对象  c_dfDIJoystick2 //标准游戏杆对象 //设置数据格式 If(DI_OK!=m_pKeyboard->SetDataFormat(&c_dfDikeyboard)) { MessageBox(HWND,"创建键盘数据格式失败!","ERROR",MB_ICONERROR|MB_OK); 43 } 2.设置键盘协调层级 HRESULTIdirectInputDevice8::SetCooperativeLevel ( HWND hwnd; //窗口 DWORD dwFlags //设备协调层级 ); HRESULT ConfigureDevices( LPDICONFIGUREDEVICESCALLBACK lpdiCallback,//每次设备改变的回 调函数 LPDICONFIGUREDEVICESPARAMS lpdiCDParams,//设备参数 DWORD dwFlags,//附加标识 LPVOID pvRefData //传给回调函数的参数 ); //下面代码设置设备的协调层级为前台非独占模式 M_pKeyboard->SetCoperativeLevel(hWND, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND; ); 3.获取键盘输入 HRESULT Acquire(VIOD); 在获取设备前必须设置好数据格式或动作映射,设备丢失时可以在窗口激活消息相应设置过程中 重新获取设备; Case WM_ACTIVATE: If(WM_INACTIVE!=wParam&&m_pKeyboard) { //窗口激活后获取设备控制权 M_pKeyboard->Acquire(); } Break; 4.读取键盘数据 (1)键盘立即数据 HRESULT GetDeviceState( DWORD cbData, //数据大小 LPVOID lpvData //数据 ) DirectInput 常见键码见课本 P335; (2)键盘缓冲数据 设置缓冲区大小 HRESULT IDirectInputDevice8::SetProperty( REFGUID rguidProp,//设置缓冲区大小,取值 DIPROP_BUFFERSIZE LPCDIPROPHEADER pdiph // ); 读取键盘缓冲数据 44 HRESULT IDirectInputDevice8::GetDeviceData( DWORD cbObjectData,// LPDIDEVICEOBJECTDATA rgdod,// LPDWORD pdwInOut,// DWORD dwFlags // ); 4.释放设备 释放设备的访问权 HRESULT Unacquire(VOID); 如果需要重新使用设备则需要调用: m_pKeyboard->Unacquire(); 5.释放对象 #deifne SAFE_RELEASE(p) if(p){p->Release();p=NULL;} SAFE_RELEASE(m_pKeyboard); SAFE_RELEASE(m_pDInput); ================================================================= ============== DirectX ================================================================= ============== DirectInput DirectInput DirectInput DirectInput 实现鼠标控制 1初始化 if (DI_OK!=DirectInput8Create(hInst,DIRECTINPUT_VERSION, IID_IDirectInput8,(LPVOID*)&m_pDInput,NULL)) { MessageBox(hWnd,"创建DInput对象失败!","ERROR",MB_OK); } if (DI_OK!=m_pDInput->CreateDevice(GUID_SysMouse,&m_pDinputMouse,NULL)) { MessageBox(HWND,"创建鼠标设备失败!","ERROR",MB_ICONERROR|MB_OK); } 2设置数据格式 P338 3设置鼠标协调层级 DISCL_EXCLUSIVE:使用该模式后光标会消失,无法点击窗口以外的其他窗口内容 DISCL_NONEXCLUSIVE:可以移动到该窗口外的点击其它任意窗口,原应用程序失去控制 权 DISCL_FOREGROUND:只有在前台模式下获取鼠标输入 DISCL_BACKgROUND :指定在前台和后台模式下都可以获取鼠标输入 4获取鼠标控制权 HRESULT Acquire(VOID); 5获取鼠标数据 使用鼠标的坐标系统 HRESULT SetProperty( 45 REFGUID rguidProp, LPCDIPROPHEADER pdiph ); rguidProp=DIPROP_AXISMODE; 定义有智能的鼠标 X=Ks*lx2/(float)FrameTime 立即数据 typedef struct DIMOUSESTATE{ LONG lX; //鼠标移动量 LONG lY; LONG lZ; BYTE rgbButtons[4]; //按键状态,最高为 1表示按下,0表示松开 }DIMOUSESTATE,*LPDIMOUSESTATE; 缓冲数据 typedef struct DIDEVICEOBJECTDATA{ DWORD dwOfs; //表示的是哪个设备对象的事件 DWORD dwData; //相当于 rgbButtons[4]中dwofs 指明 的哪个 DWORD dwTimeStamp; DWORD dwSequence; UINT_PTR uAppData; }DIDEVICEOBJECTDATA,*LPDIDEVICEOBJECTDATA; typedef const DIDEVICEOBJECTDATA*LPCDIDEVICEOBJECTDATA; 第一个参数 dwOfs 可取值为 DIMOFS_BUTTON0---- DIMOFS_BUTTON07 DIMOFS_X DIMOFS_Y DIMOFS_Z 6处理鼠标丢失 使用 Acquire 函数重新获取设备 7释放设备 #deifne SAFE_RELEASE(p) if(p){p->Release();p=NULL;} SAFE_RELEASE(m_pDInputMouse); SAFE_RELEASE(m_pDInput); ================================================================= ============== DirectX ================================================================= ============== 鼠标拣选 111 1 获取投影点 2计算拾取射线 下面代码片断就是通过单击屏幕上的一个点来计算出拾取射线 Ray CalculateRay() 46 { float px = 0.0f; float py = 0.0f; //获取视口大小 D3DVIEWPORT9 vp; m_pDevice->GetViewport(&vp); D3DXMATRIX proj; m_pDevice->GetTransform(D3DTS_PROJECTION,&proj); //计算拾取射线 px = (((2.0f*x)/vp.Width)-1.0f)/proj._11; py = (((-2.0f*y)/vp.Height)+1.0f)/proj._22; Ray ray; ray._origin = (0,0,0); ray._dirction = (px,py,1); return ray; } 3射线转换 下面的代码片断将拾取射线转换到世界空间中 Ray TransformRay(Ray ray,D3DXMATRIX* T) { ray transRay; //转换射线的起点 D3DXVec3TransformCoord(&transRay._origin,&ray._origin,T); //转换射线的方向 D3DXVec3TransformNormal(&transRay._dirction,&ray._dirction,T); D3DXVec3Normalize(&transRay._dirction,&transRay._dirction); return transRay; } ================================================================= ============== DirectX ================================================================= ============== 47 游戏音乐音效 ================================================================= ============== DirectX ================================================================= ==============
还剩46页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

knlkxw

贡献于2012-03-19

下载需要 15 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf