----------------------- 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
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