----------------------- Page 1----------------------- DirectX 网络游戏开发— DDiirreeccttXX 函数归纳总结 23003 2233000033 李翔 李 森 1 ----------------------- Page 2----------------------- DirectX DDiirreeccttXX目录 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 2 ----------------------- Page 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 3 ----------------------- Page 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 4 ----------------------- Page 5----------------------- 创建3D文字网格...................................... 2 8. ...................................... 4 88..游戏控制 ............................................................................ 44 ............................................ DirectInput实现键盘控制 ........................................................................................ ................................................................ 2 ............................................ DirectInput实现鼠标控制 ........................................................................................ ................................................................ 2 ...........................................................鼠标键选 ...................................................................................................................... ................................................................ 2 9.游戏音乐音效....................................4 5 ----------------------- Page 6----------------------- D3D DD33DD基本框架 D3D 创建DD33DD对象: Direct3DCreate9(D3D_SDK_VERSION) ================================================================= ============== DirectX ================================================================= ============== 获取显卡显示模式: HRESULT GetAdapterDisplayMode( UINT Adapter, //指定显示卡序列号 D3DDISPLAYMODE *pMode //存储显示模式的指针 ); ================================================================= ============== DirectX ================================================================= ============== D3D 创建DD33DD 设备接口: 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是多线程安全的,设置该项 会降低系统性能 6 ----------------------- Page 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 ================================================================= ============== 屏幕反转: 7 ----------------------- Page 8----------------------- HRESULT Present( CONST RECT *pSourceRect, //复制源的矩形区域指针 CONST RECT *pDestRect, //复制目的地的矩形区域指针 HWND hDestWindowOverride, //D3D设备窗口句柄 CONST RGNDATA *pDirtyRegion //最小更新区域指针 ); 注意: 除非D3D的交换链是用D3DSWAPEFFECT_COPY的标志创建,在大多数的情况下,此 函数的各个参数都设置为NULL。 ================================================================= ============== DirectX ================================================================= ============== 绘制基本图形 FVF 灵活定点格式(FFVVFF) 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提供的灵活顶点格式,就可以定义自己的顶点结构体,例如,定义一个包含 经过变换的坐标信息和漫反射颜色信息的顶点结构如下: //创建顶点对象 LPDIRECT3DVERTEXBUFFER9g_pVB = NULL; //顶点缓冲区对象 //自定义顶点格式 struct CUSTOMVERTEX { FLOAT x,y,z,rhw; //经过变换的三维坐标 DWORD color; //顶点漫反射颜色 }; #define D3DFVF_CUSTOMVERTEX(D3DFVF_XYZRHW| D3DFVF_DIFFUSE) //以下函数设置顶点数据 CUSTOMVERTEXvertices[]= { 8 ----------------------- Page 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, //顶点缓冲区属性 DWORD FVF, //灵活顶点格式 D3DPOOL Pool, //顶点缓冲区的内存类型 IDirect3DVertexBuffer9** ppVertexBuffer, //顶点缓冲区指针地址 HANDLE* pSharedHandle //保留参数,置为0 ); *Usage:参数Usage用于指定顶点缓冲区的属性,其取值可以设为0,或下面任意值的组合。 D3DUSAGE_WRITEONLY //只写属性,不能进行读操作,设置该属性可以提高系统性能 D3DUSAGE_DYNAMIC //指定顶点缓冲区要求使用动态内存 D3DUSAGE_NPATCHES //使用顶点缓冲区绘制N-patches曲线 D3DUSAGE_POINTS //指定顶点缓冲区存储原始点 D3DUSAGE_RTPATCHES //使用顶点缓冲区绘制高阶图元(high-orderprimitive) 9 ----------------------- Page 10----------------------- D3DUSAGE_SOFTWAREPROCESSING //使用软件进行顶点运算,否则使用硬件计算 *Pool:参数Pool属于枚举类型D3DPOOL,指定顶点缓冲区资源的内存位置,如下: typedef enum _D3DPOOL { D3DPOOL_DEFAULT = 0, // DD33DDPPOOOOLL__DDEEFFAAUULLTT == 00,, ////默认值,顶点缓冲区尽可能存在于显存中 D3DPOOL_MANAGED = 1, // D3D DD33DDPPOOOOLL__MMAANNAAGGEEDD == 11,, ////由DD33DD的资源管理器自动调度顶点缓冲 区内存位置 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, DWORD FVF :D3DFVF_CUSTOMVERTEX, D3DPOOL Pool:D3DPOOL_DEFAULT, ppVertexBuffer:& g_pVB, pSharedHandle:NULL))) { returnE_FAIL; } ================================================================= ============== DirectX ================================================================= ============== 保存顶点 HRESULT Lock( UINT OffsetToLock, //加锁内存起始地址 UINT SizeToLock, //加锁内存大小 VOID **ppbData, //返回内存指针地址 DWORD Flags //加锁属性 ); DWORD Flags DDWWOORRDD FFllaaggss:指定了顶点缓冲区的加锁属性,它可以取值为0,或者如下中的任意组合: D3DLOCK_DISCARD //仅在动态缓冲区下使用,硬件丢弃原缓冲区并创建一个 新的缓冲区 D3DLOCK_NO_DIRTY_UPDATE //在缺省状态下,对缓冲区加锁将会在该区域设置一个 Dirty标志,该属性将不对该区域设置Dirty标志 D3DLOCK_NOSYSLOCK //在加锁的过程中系统可进行其他操作 D3DLOCK_READONL //设置缓冲区位制度属性 D3DLOCK_NOOVERWRITE //尽在动态缓冲区下使用,保证不覆盖缓冲区数据,即向 10 ----------------------- Page 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( DWORD FVF //灵活顶点格式 ); *绘制基本图元 HRESULT DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, //绘制的图元类型 11 ----------------------- Page 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:全局变量 //----------------------------------------------------------------------------- LPDIRECT3DVERTEXBUFFER9g_pVB =NULL;// 顶点缓冲区对象 LPDIRECT3DINDEXBUFFER9 g_pIB =NULL;// 索引缓冲区对象 //----------------------------------------------------------------------------- // Desc:顶点结构和灵活顶点格式 //----------------------------------------------------------------------------- structCUSTOMVERTEX { FLOATx, y, z, rhw; // 经过坐标转换的顶点位置 DWORDcolor; // 顶点漫反射颜色值 }; #defineD3DFVF_CUSTOMVERTEX(D3DFVF_XYZRHW|D3DFVF_DIFFUSE) 12 ----------------------- Page 13----------------------- //----------------------------------------------------------------------------- // Desc:创建顶点缓冲区和索引缓冲区 //----------------------------------------------------------------------------- HRESULTInitVBAndIB() { //顶点数据 CUSTOMVERTEXg_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(inti=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; } //顶点索引数组 WORDg_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) )) { 13 ----------------------- Page 14----------------------- returnE_FAIL; } //创建索引缓冲区 if( FAILED(g_pd3dDevice->CreateIndexBuffer(24*sizeof(WORD), 0, D3DFMT_INDEX16, //索引类型 D3DPOOL_DEFAULT,&g_pIB,NULL) )) { returnE_FAIL; } ================================================================= ============== DirectX ================================================================= ============== 保存顶点索引值 //填充顶点缓冲区 VOID*pVertices; if(FAILED(g_pVB->Lock(0, sizeof(g_Vertices),(void**)&pVertices,0) ) ) returnE_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 )) ) returnE_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, //索引缓冲区的起始位置 14 ----------------------- Page 15----------------------- UINT PrimitiveCount //绘制的基本图元数量 ); //----------------------------------------------------------------------------- // Desc:渲染图形 //----------------------------------------------------------------------------- VOIDRender() { //清空后台缓冲区 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 DD33DD中的图形学 D3D DD33DD中的向量 D3DXVECTOR3 DD33DDXXVVEECCTTOORR33表示三维向量; * **向量相等 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; 15 ----------------------- Page 16----------------------- bool Equals(float 1hs,float rhs) { Return fabs(1hs - rhs)<EPSILON; } //完全不用在意这些事,因为D3DXVECTOR3的重载运算符已经完成了这些 功能 *D3D **DD33DD向量模的计算 表示向量长度: FLOAT D3DXVec3Length ( CONST D3DXVECTOR3 *PV //需要求模的向量 ) 例: D3DVECTOR3 v(1.0f,2.0f,3.0f); Float magnitude = D3DXVec3Length(&v); * **向量规格化 D3DXVECTOR3 *WINAPI D3DXVec3Normalize( D3DXVECTOR3 *pOut, //输出单位向量 CONST D3DXVECTOR3 *pV //输入的向量 ); * **向量加法 D3DVECTOR3 U(2.0F,0.0F,1.0F); D3DVECTOR3 V(0.0F,-1.0F,5.0F); D3DVECTOR3 SUM = U + V; * **向量减法 D3DVECTOR3 U(2.0F,0.0F,1.0F); D3DVECTOR3 V(0.0F,-1.0F,5.0F); D3DVECTOR3 SUM = U - V; * **数乘 D3DVECTOR3 U(2.0F,0.0F,1.0F); D3DVECTOR3 scaledVec = U * 10.0f; * **点乘 FLOAT D3DXVec3Dot( CONST D3DVECTOR3 *PV1; CONST D3DVECTOR3 *PV2; ) 例: D3DVECTOR3 U(2.0F,0.0F,1.0F); D3DVECTOR3 V(0.0F,-1.0F,5.0F); 16 ----------------------- Page 17----------------------- float dot = D3DXVec3Dot(&u,&v); ================================================================= ============== DirectX ================================================================= ============== D3D DD33DD中的矩阵 * **矩阵乘法 D3DXMATRIX A(…); D3DXMATRIX B(…); D3DXMATRIX C = A * B; * **矩阵元素设置 1)使用”.”运算符 D3DXMATRIX A; A._11 = 1.0f; 2)使用()运算符 D3DXMATRIX M; M ( 0 , 0 ) = 5.0f; * **单位矩阵 D3DXMATRIX *D3DXMatrixIdentity( D3DXMATRIX *pOut ); D3DXMATRIX M; D3DXMatrixIdentity(&M); * **矩阵转置 D3DXMATRIX *WINAPI D3DXMatrixTranspose( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM ); * **逆矩阵 D3DXMATRIX *WINAPI D3DXMatrixInverse( D3DXMATRIX *pOut, FLOAT *pDeterminant, //通常忽略第二个参数都设置为0 CONST D3DXMATRIX *pM ); 例: D3DXMATRIX A(…); D3DXMATRIX B; D3DXMatrixInverse (&B,0,&A); ================================================================= ============== DirectX ================================================================= ============== 17 ----------------------- Page 18----------------------- D3D DD33DD中的平面 平面的描述 D3D中的平面 点与平面之间的关系 平面的构造 平面单位化 平面变换 ================================================================= ============== DirectX ================================================================= ============== D3D DD33DD中的射线 射线与平面相交判断 ================================================================= ============== DirectX ================================================================= ============== D3D DD33DD中的图形变换 HRESULT SetTransform( D3DTRANSFORMSTATETYPE State, //变换类型 CONST D3DMATRIX* pMatrix //变换矩阵 ); 参数State可以是一下任意类型: D3DTS_WORLD //世界变换 D3DTS_VIEW //视图变换 D3DTS_PROJECTION //投影变换 *平移变换 D3DXMATRIX *WINAPI D3DXMatrixTranslation( D3DXMATRIX *pOut, //输出矩阵 FLOAT x, //X轴上的平移量 FLOAT y, //Y轴上的平移量 FLOAT z //Z轴上的平移量 ); *缩放变换 D3DXMATRIX *WINAPI D3DXMatrixScaling( D3DXMATRIX *pOut, //输出矩阵 FLOAT sx, //X轴上的缩放量 FLOAT sy, //Y轴上的缩放量 FLOAT sz //Z轴上的缩放量 ); *旋转变换 18 ----------------------- Page 19----------------------- D3DXMATRIX *WINAPI D3DXMatrixRotationX( //绕X轴旋转 D3DXMATRIX *pOut, //输出矩阵 FLOAT Angle //旋转角度 ); D3DXMATRIX *WINAPI D3DXMatrixRotationY( //绕Y轴旋转 D3DXMATRIX *pOut, //输出矩阵 FLOAT Angle //旋转角度 ); D3DXMATRIX *WINAPI D3DXMatrixRotationZ( //绕Z轴旋转 D3DXMATRIX *pOut, //输出矩阵 FLOAT Angle //旋转角度 ); D3DXMATRIX *WINAPI D3DXMatrixRotationAxis( //绕任意轴旋转 D3DXMATRIX *pOut, //输出矩阵 CONST D3DXVECTOR3 *Pv //旋转中心轴向量 FLOAT Angle //旋转角度 ); *组合变换 D3DXMATRIX *WINAPI D3DXMatrixMultiply( D3DXMATRIX *pOut, //输出变换矩阵 CONST D3DXMATRIX *pM1, //输入矩阵 CONST D3DXMATRIX *pM2 //输入矩阵 ); ================================================================= ============== DirectX ================================================================= ============== 19 ----------------------- Page 20----------------------- 纹理 从磁盘文件获取纹理 HRESULT WINAPI D3DXCreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, //Direct3D设备指针 LPCTSTR SrcFile, //纹理图形文件 LPDIRECT3DTEXTURE9 *ppTexture //存储Direct3D纹理的指针地址 ); 该函数支持的图形文件类型:bmp、dds、dib、jpg、png以及tga等。 ================================================================= ============== DirectX ================================================================= ============== 设置当前要渲染的纹理 HRESULT SetTexture( DWORD Stage, //多级纹理的索引,从0-7,单层纹理取0 IDirect3DBaseTexture9 *pTexture //Direct3D的纹理接口指针 ); ================================================================= ============== DirectX ================================================================= ============== 设置纹理的渲染状态 HRESULT SetTextureStageState( DWORD Stage, //当前设置的多级纹理的索引 D3DTEXTURESTAGESTATETYPE Type, //纹理渲染状态的类型 DWORD Value //纹理渲染状态的值,与类型相对应 ); 第二个参数D3DTEXTURESTAGESTATETYPE Type取值: typedef enum _D3DTEXTURESTAGESTATETYPE { D3DTSS_COLOROP = 1, //纹理层的颜色混合方式 D3DTSS_COLORARG1 = 2, //颜色混合的第一个参数 20 ----------------------- Page 21----------------------- D3DTSS_COLORARG2 = 3, //颜色混合的第二个参数 D3DTSS_ALPHAOP = 4, //指定纹理层的Alpha透明 D3DTSS_ALPHAARG1 = 5, //Alpha混合的第一个参数 D3DTSS_ALPHAARG2 = 6, //Alpha混合的第二个参数 D3DTSS_BUMPENVMAT00 = 7, //绘制凹凸纹理时 D3DTSS_BUMPENVMAT01 = 8, //绘制凹凸纹理时 D3DTSS_BUMPENVMAT10 = 9, //绘制凹凸纹理时 D3DTSS_BUMPENVMAT11 = 10, //绘制凹凸纹理时 D3DTSS_TEXCOORDINDEX = 11, //该纹理层使用的纹理坐标的索引 D3DTSS_BUMPENVLSCALE = 22, //绘制凹凸纹理的缩放参数 D3DTSS_BUMPENVLOFFSET = 23, //绘制凹凸纹理的平移参数 D3DTSS_TEXTURETRANSFORMFLAGS = 24, //控制纹理坐标的转换标志 D3DTSS_COLORARG0 = 26, //指定混合过程的第三个颜色 D3DTSS_ALPHAARG0 = 27, //Alpha混合的第三个参数 D3DTSS_RESULTARG = 28, //颜色混合的结果输出寄存器 D3DTSS_CONSTANT = 32, //颜色混合的常量寄存器 D3DTSS_FORCE_DWORD = 0x7fffffff //强制转换为32位,用于占位 } D3DTEXTURESTAGESTATETYPE; ================================================================= ============== DirectX ================================================================= ============== 设置纹理采样属性 HRESULT SetSamplerState( DWORD Sampler, //指定纹理采样属性的纹理层ID(0~7) D3DSAMPLERSTATETYPE Type, //纹理过滤类型 DWORD Value //设置纹理采样属性值 ); 第二个参数D3DSAMPLERSTATETYPE Type取值: D3DSAMP_MAGFILTER //处理放大过滤 D3DSAMP_MINFILTER //处理缩小过滤 D3DSAMP_MIPFILTER //多纹理过滤 D3DSAMP_MIPMAPLODBIAS //多级纹理级数偏移值,初始值为0 D3DSAMP_MAXMIPLEVEL //最大多纹理级别,初始值为0 D3DSAMP_MAXANISOTROPY //各向异性,初始为1 第三个参数Value取值: D3DTEXF_NONE //不使用特殊的采样方式 D3DTEXF_POINT //最近点采样 D3DTEXF_LINEAR //线性纹理采样 D3DTEXF_ANISOTROPIC //各向异性纹理采样 ================================================================= ============== DirectX 21 ----------------------- Page 22----------------------- ================================================================= ============== 从一张纹理图形中生成多级纹理 HRESULT WINAPI D3DXCreateTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, //Direct3D设备指针 LPCTSTR pSrcFile, //图形文件路径与文件名 UINT Width, //指定纹理宽度 UINT Height, //指定纹理高度 UINT MipLevels, //指定渐进纹理序列级数。设为0表示尽可能多 的生成纹理过滤序列,直到最小纹理的宽度和高度等 于1 DWORD Usage, //纹理使用方式,一般为0 D3DFORMAT Format, //指定纹理图形格式 D3DPOOL Pool, //纹理存放的内存类型,一般为0 DWORD Filter, //纹理过滤方式 DWORD MipFilter, //自动生成的纹理序列过滤方式 D3DCOLOR ColorKey, //设置透明色 D3DXIMAGE_INFO *pSrcInfo, //图形文件信息存放地址,可设为0 PALETTEENTRY *pPalette, //调色板存储地址 LPDIRECT3DTEXTURE9 *ppTexture //创建的Direct3D纹理指针存放地址 ); ================================================================= ============== DirectX ================================================================= ============== 包装纹理寻址 SetSamplerState(0 , D3DSAMP_ADDRESSU , D3DTADDRESS_WRAP); SetSamplerState(0 , D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); ================================================================= ============== DirectX ================================================================= ============== 镜像纹理寻址 SetSamplerState(0 , D3DSAMP_ADDRESSU , D3DTADDRESS_MIRROR); SetSamplerState(0 , D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR); ================================================================= ============== DirectX ================================================================= ============== 夹取纹理寻址 SetSamplerState(0 , D3DSAMP_ADDRESSU , D3DTADDRESS_CLAMP); 22 ----------------------- Page 23----------------------- SetSamplerState(0 , D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); ================================================================= ============== DirectX ================================================================= ============== 边框颜色纹理寻址 SetSamplerState(0 , D3DSAMP_BORDERCOLOR , 0xffff0000); //设置边框颜 色 SetSamplerState(0 , D3DSAMP_ADDRESSU , D3DTADDRESS_BORDER); SetSamplerState(0 , D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER; ================================================================= ============== DirectX ================================================================= ============== 一次镜像纹理寻址 SetSamplerState(0 , D3DSAMP_ADDRESSU , D3DTADDRESS_MIRRORONCE); SetSamplerState(0 , D3DSAMP_ADDRESSV, D3DTADDRESS_MIRRORONCE); ================================================================= ============== DirectX ================================================================= ============== 纹理包装 SetRenderState(D3DRS_WRAP0 , D3DWRAP_U|D3DWRAP_V); //设置在u和v方向 上同时使用纹理包装 ================================================================= ============== DirectX ================================================================= ============== 光照 D3D DD33DD中光照的基本实现 顶点格式 struct CUBE_CUSTOMVERTEX { FLOAT x,y,z; //顶点位置坐标 FLOAT tu,tv; //纹理坐标 FLOAT nx,ny,nz; //顶点法线 23 ----------------------- Page 24----------------------- }; //定义顶点格式 #define CUBE_D3DFVF_CUSTOMVERTEX \ (D3DFVF_XYZ|D3DFVF_TEX1|D3DFVF|NORMAL) ================================================================= ============== DirectX ================================================================= ============== 设置物体材质 typedef struct _D3DMATERIAL9 { D3DCOLORVALUE Diffuse; //漫反射 D3DCOLORVALUE Ambient; //环境光 D3DCOLORVALUE Specular; //镜面反射 D3DCOLORVALUE Emissive; //物体本身发光强度 float Power; //镜面反射高光POWER越大,与周围亮度 差距越大 } D3DMATERIAL9; //表示完物体之后需要调用SetMaterial为当前渲染像素点设置材质 HRESULT SetMaterial( CONST D3DMATERIAL9* pMaterial //指向定义材质的指针 ); 漫反射: D3DMATERIAL9 mtrl; ZeroMemory(&mtrl,sizeof(D3DMATERIAL9)); mtrl.Diffuse.r = 0.8f; mtrl.Diffuse.g = 0.6f; mtrl.Diffuse.b = 0.5f; mtrl.Diffuse.a = 0.1f; m_pD3Ddevice->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); ================================================================= ============== 24 ----------------------- Page 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 , , 3 设置光源时首先定义一个DD33DDLLIIGGHHTT99类型的结构体,,接下来为对应的光源类型填充其属性,,以下的代码片段定义了33 : 中类型的光源:: #define LIGHT_TYPE 1 // ##ddeeffiinnee LLIIGGHHTT__TTYYPPEE 11 ////用宏定义说明选择的光源类型 D3DLIGHT9 d3dLight; DD33DDLLIIGGHHTT99 dd33ddLLiigghhtt;; Memset(&d3dLight,0,sizeof(d3dlight)); MMeemmsseett((&&dd33ddLLiigghhtt,,00,,ssiizzeeooff((dd33ddlliigghhtt))));; LightType = LIGHT_TYPE; LLiigghhttTTyyppee == LLIIGGHHTT__TTYYPPEE;; switch(LightType) sswwiittcchh((LLiigghhttTTyyppee)) { {{ Case 1: // CCaassee 11:: ////点光源 Break; BBrreeaakk;; Case 2: // CCaassee 22:: ////平行光 Break; BBrreeaakk;; Case 3: // CCaassee 33:: ////聚光灯 Break; BBrreeaakk;; } }} 25 ----------------------- Page 26----------------------- ================================================================= ============== DirectX ================================================================= ============== 激活光照运算 激活光照运算的渲染状态 //m_pDevice为有效的D3D设备句柄 m_Device->SetRenderState(D3DRS_LIGHTING,TRUE); 指定光源 HRESULT SetLight HHRREESSUULLTT SSeettLLiigghhtt ( (( DWORD Index, DDWWOORRDD IInnddeexx,, //取值0-7表示设置光源的序号值 CONST D3DLIGHT9 *pLight CCOONNSSTT DD33DDLLIIGGHHTT99 **ppLLiigghhtt //指向一个表示特定光源的指针 ); ));; // 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 ================================================================= ============== 摄像机 生成视图变换矩阵 26 ----------------------- Page 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 ================================================================= ============== 27 ----------------------- Page 28----------------------- 模型基础 ID3DXMesh IIDD33DDXXMMeesshh接口基础 几何信息的获取 //获取顶点缓冲 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; 28 ----------------------- Page 29----------------------- Mesh->LockAttributeBuffer(lockingFlags,&buffer); //对属性缓冲区进行操作 Mesh->UnlockAttributeBuffer(); 渲染 HRESULT DrawSubset( DWORD AttribId //属性ID指示Mesh中的子集,按照子集的ID渲染哪 个图形 ); 例: 1.Mesh->DrawSubset(0); 2.for(int i = 0;i<numSubsets;i++) { Device->SetMaterial(mtrls[i]); Device->SetTexture(0,textures[i]); Mesh->DrawSubset(i); } ================================================================= ============== DirectX ================================================================= ============== ID3DXMesh IIDD33DDXXMMeesshh接口相关 Mesh 优化MMeesshh HRESULT OptimizeInplace( DWORD Flags, //执行优化的类型 CONST DWORD *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]; 29 ----------------------- Page 30----------------------- Mesh->OptimizeInplace( D3DXMESHOPT_ATTRSORT| D3DXMESHOPT_COMPACT| D3DXMESHOPT_VERTEXCACHE, adjacencyInfo, optimizedAdjacencyInfo, 0, 0); 还有一种方法是输出一个优化后的Mesh而不是在原来的基础上修改; HRESULT Optimize( DWORD Flags, //执行优化的类型 CONST DWORD *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方法直接修改属性表。 30 ----------------------- Page 31----------------------- D3DXATTRIBUTERANGE attributeTable[12]; //填充属性表的值 Mesh->SetAttributeTable(attributeTable,12); ================================================================= ============== DirectX ================================================================= ============== .X 应用..XX文件 1. 11..提取多边形网格信息: HRESULT WINAPI 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"Couldnot findgame.x",L"Mesh",MB_OK); returnE_FAIL; } 2.ID3DXBuffer : 22..IIDD33DDXXBBuuffffeerr接口:: GetBufferPointer();//返回指向数据块首地址的指针 GetBufferSize(); //返回数据块中的大小 ID3DXBuffer 注意: IIDD33DDXXBBuuffffeerr 指向的数据块本身是没有数据类型的,所以需要强制转换, 同时 ID3DXBuffer本身也是一个COM对象,所以使用完之后需要调用Release方法释放. 例如: D3DXMATERIAL*d3dxMaterials= (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); pD3DXMtrlBuffer->Release(); 3.载入纹理和材质: 31 ----------------------- Page 32----------------------- typedef struct D3DXMATERIAL { D3DMATERIAL9 MatD3D; //物体的材质信息 LPSTR pTextureFilename; //物体的纹理文件名称 } D3DXMATERIAL; 下面程序片断用于获取3D模型的材质和纹理信息: //从材质集合中把材质和纹理信息解压读取出来 D3DXMATERIAL*d3dxMaterials= (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); g_pMeshMaterials= newD3DMATERIAL9[g_dwNumMaterials]; g_pMeshTextures = newLPDIRECT3DTEXTURE9[g_dwNumMaterials]; 注意:函数D3DXLoadMeshFromX调用成功后返回的是一个材质结构体数组,第i个材质信息 对应的第i个网格模型的子集,因此可以使用简单的循环来对整个网格进行渲染; for(DWORDi=0; i<g_dwNumMaterials;i++ ) { //拷贝材质 g_pMeshMaterials[i]= d3dxMaterials[i].MatD3D; //设置材质漫反射的颜色 g_pMeshMaterials[i].Ambient= g_pMeshMaterials[i].Diffuse; //创建纹理 if(FAILED(D3DXCreateTextureFromFile(g_pd3dDevice, d3dxMaterials[i].pTextureFilename, & g_pMeshTextures[i]))) { g_pMeshTextures[i]=NULL; } } //释放材质缓冲区的内容; pD3DXMtrlBuffer->Release(); 4. 44..绘制网格模型 下面代码片断就是一个网格模型的渲染函数: //逐块渲染网格模型 for( DWORDi=0;i<g_dwNumMaterials;i++ ) { //设置材料和纹理 g_pd3dDevice->SetMaterial(&g_pMeshMaterials[i]); g_pd3dDevice->SetTexture(0, g_pMeshTextures[i]); //渲染模型 g_pMesh->DrawSubset(i ); } ================================================================= ============== DirectX ================================================================= ============== 32 ----------------------- Page 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; //打开深度测试 } ================================================================= 33 ----------------------- Page 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 激活AAllpphhaa混合 g_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE); ================================================================= 34 ----------------------- Page 35----------------------- ============== DirectX ================================================================= ============== Alpha 设置AAllpphhaa混合计算方式 g_pDevice->SetRenderState( D3DRS_BLENDOPALPHA, D3DBLENDOP); D3DBLENDOP取值: D3DBLENDOP_ADD //源计算结果与颜色缓冲区计算结果相 加 D3DBLENDOP_SUBTRACT //源计算结果减去颜色缓冲区计算结果 D3DBLENDOP_REVSUBTRACT //颜色缓冲区计算结果减去源计算结果 D3DBLENDOP_MIN //取两者的最小值 D3DBLENDOP_MAX //取两者的最大值 ================================================================= ============== DirectX ================================================================= ============== Alpha 设置AAllpphhaa混合系数 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); ================================================================= ============== 35 ----------------------- Page 36----------------------- DirectX ================================================================= ============== 设置Alpha测试参考值 g_pDevice->SetRenderState( D3DRS_ALPHAREF, AlphaReference); AlphaReference取值范围:0x00000000 ~0x000000ff ================================================================= ============== DirectX ================================================================= ============== 设置Alpha测试函数 g_pDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMPFUNC); 枚举类型变量D3DCMPFUNC取值可参考深度缓冲部分D3DCMPFUNC的取值。 ================================================================= ============== DirectX ================================================================= ============== ( Fillmode ) 多边形填充模式(( FFiillllmmooddee )) 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表示对 系统当前默认使用的图形显示硬件进行查询。 36 ----------------------- Page 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 //取前一个纹理层的输出颜色 37 ----------------------- Page 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值对雾没有影响 ================================================================= 38 ----------------------- Page 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 ================================================================= ============== 2D 创建22DD字体 HRESULT WINAPI D3DXCreateFont( LPDIRECT3DDEVICE9 pDevice, //Direct3D设备 INT Height, //字体高度 39 ----------------------- Page 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, //指定用于显示的字符串 40 ----------------------- Page 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 ================================================================= ============== 3D 创建33DD文字网格 HRESULT WINAPI 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 DDiirreeccttIInnppuutt实现键盘控制 41 ----------------------- Page 42----------------------- 创建DirectInput对象: HRESULT WINAPI 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); } 创建设备对象: HRESULT IdirectInput8::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); 42 ----------------------- Page 43----------------------- } 2.设置键盘协调层级 HRESULT IdirectInputDevice8::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 // ); 读取键盘缓冲数据 43 ----------------------- Page 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 DDiirreeccttIInnppuutt实现鼠标控制 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( 44 ----------------------- Page 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 ================================================================= ============== 鼠标拣选 1 11获取投影点 2计算拾取射线 下面代码片断就是通过单击屏幕上的一个点来计算出拾取射线 Ray CalculateRay() 45 ----------------------- Page 46----------------------- { floatpx = 0.0f; floatpy = 0.0f; //获取视口大小 D3DVIEWPORT9vp; m_pDevice->GetViewport(&vp); D3DXMATRIXproj; 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); returnray; } 3射线转换 下面的代码片断将拾取射线转换到世界空间中 Ray TransformRay(Rayray,D3DXMATRIX*T) { ray transRay; //转换射线的起点 D3DXVec3TransformCoord(&transRay._origin,&ray._origin,T); //转换射线的方向 D3DXVec3TransformNormal(&transRay._dirction,&ray._dirction,T); D3DXVec3Normalize(&transRay._dirction,&transRay._dirction); returntransRay; } ================================================================= ============== DirectX ================================================================= ============== 46 ----------------------- Page 47----------------------- 游戏音乐音效 ================================================================= ============== DirectX ================================================================= ============== 47