----------------------- 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 );
}
=================================================================
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, //指定用于显示的字符串