网络游戏客户端编程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学习目标
1.掌握深度缓冲、Alpha混合和Alpha测试
2.掌握多边形填充模式和渲染模式,图形反锯齿
3.掌握多纹理混合、雾化效果
4.掌握2D文字和图形、公告板技术
5.掌握粒子系统
知识背景
1.熟练掌握Windows编程
2.掌握D3D程序的基本框架
3.掌握如何在D3D环境下显示模型和场景
本章要点
1.Alpha混合和Alpha测试
2.多纹理混合,雾化效果
3.2D文字和图形显示
4.粒子系统
引言
游戏中逼真的场景、漂亮的人物和华美的服装,都是通过在程序中组合一个个基本图元,经过变换后渲染出来的。单纯的渲染并不能生成游戏中的各种特效,比如雾效、爆炸的火焰效果等。要实现这些特效,就要在基本图形渲染的基础上,采用一些特殊的技术。本章将学习如何在D3D环境下实现一些简单的游戏特效。
6.1 基本渲染属性
6.1.1 深度缓冲
深度缓冲区是Direct3D用来存储绘制到屏幕上的每一个像素点的深度信息的一块内存缓冲区。Direct3D通过比较当前绘制的像素点的深度和对应深度缓冲区的点的深度值来决定是否绘制当前像素。如果深度测试为TRUE,则绘制当前像素,并用当前像素点深度值更新深度缓冲区,反之则不予绘制。通常情况下,深度缓冲区对应于屏幕大小的一块二维区域。
深度缓冲(又称Z-buffer)的作用是确保多边形能够正确地显示在它们本来的深度(相对于摄像机)上。例如在场景中有两个矩形,一个是蓝色的而另一个是绿色的。蓝色的Z值为10,绿色的Z值为20(摄像机在原点)。这就意味着蓝色的在绿色的前面(如图6-1所示)。深度缓冲能确定哪个对象在另一个对象的前面,正确地渲染对象。DirectX会测试对象在屏幕上的像素点到摄像机的远近,并把得出的值保存在深度缓冲中;接着,DirectX会测试同一位置另一对象的像素点,并和刚才的像素进行比较,如果更近,就刷新刚才的记录,否则就不理睬(有东西在它前面挡着它),这会决定此位置像素点的颜色到底是蓝色的还是绿色的。
图6-1 深度测试
下面的程序片断开启了深度测试,以便得到物体正确的前后关系:
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
// g_pD3D为有效的Direct3D设备
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
在显示模式中,设定了d3dpp.EnableAutoDepthStencil的值为TRUE,表示打开深度测试。接着,d3dpp.AutoDepthStencilFormat的值设为D3DFMT_D16,表示深度缓冲区的每一个像素由16位的整数值表示。
接下来,调用Direct3D渲染状态设置函数IDirect3DDevice9∷SetRenderState()激活深度缓冲区,将第一个参数设为D3DRS_ZENABLE,表示设置深度缓冲的状态,将第二个参数设为TRUE,打开深度缓冲。
// g_pd3dDevice为有效的Direct3D设备
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
接下来,仍然调用IDirect3DDevice9∷SetRenderState()设置深度测试函数,将第一个参数设为D3DRS_ZFUNC,将第二个参数设为想要设置的深度测试函数,它属于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,表示当测试点深度值小于深度缓冲中的相应值时返回TRUE,通过深度测试并绘制相应的像素点。
// g_pd3dDevice为有效的Direct3D设备
g_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESS );
最后,还要调用IDirect3DDevice9∷SetRenderState(),将第一个参数设为
D3DRS_ ZWRITEENABLE,将第二个参数设为TRUE,允许应用程序在绘制像素时更新深度缓冲区:
// g_pd3dDevice为有效的Direct3D设备
g_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE );
6.1.2 Alpha混合
在前面章节的介绍中,已经遇到了Alpha值,如D3DCOLORVALUE数据结构中的A,它并没有被使用,因为在程序中没有激活Alpha混合(Alpha Blending),并且Alpha总是被赋值为浮点值1.0f(在默认渲染状态下,Alpha为1.0f表示不透明)。本节将讨论Alpha值的使用和半透明物体的绘制。
前面介绍的程序范例中,绘制图形的颜色总是替换当前颜色缓冲区中存在的颜色值,这样,后画的物体总是覆盖在原有物体上。但是,当想要绘制类似于玻璃、水等具有透明效果的物体时,这种方法显然不能满足要求。通过定义一个表示物体半透明度的Alpha值和一个半透明计算公式,可以把要绘制的物体的颜色与颜色缓冲区中存在的颜色相混合,从而绘制出具有半透明效果的物体。
Direct3D计算Alpha混合的颜色方法如下: