您也需要设定屏蔽参照值,这就是让屏蔽函式用来测试的屏蔽缓冲区,作法如下:
//
//设定屏蔽参照值。 //
lpDev7->SetRenderState(D3DRENDERSTATE_STENCILREF,newRef);
在执行某个像素的屏蔽测试前,Direct3D会将屏蔽参照值和一个屏蔽mask值作AND位运算,并用屏蔽比较函式将结果与屏蔽缓冲区的内容作比较,您可以用下列指令设定屏蔽mask:
//
//设定屏蔽mask。. //
lpDev7->SetRenderState(D3DRENDERSTATE_STENCILMASK, newStencilMask);
您可以用以下指令定义屏蔽测试失败时的动作:
//
//定义屏蔽测试失败时的动作。 //
lpDev7->SetRenderState(D3DRENDERSTATE_STENCILFAIL, D3DSTENCILOP_REPLACE);
第二个参数是取自D3DSTENCILOP列举型态的值。
您可以用以下指令定义屏蔽测试成功但深度缓冲区测试失败时的因应方式:
//
//屏蔽测试成功但深度缓冲区测试失败 //的处理动作。 //
lpDev7->SetRenderState(D3DRENDERSTATE_STENCILZFAIL, D3DSTENCILOP_REPLACE);
第二个传入的参数是来自D3DSTENCILOP列举型态。
最后,您可以用以下指令定义屏蔽测试和测度缓冲区测试都成功时的作法:
//
//屏蔽测试和测度缓冲区测试都成功时 //的处理动作。 //
lpDev7->SetRenderState(D3DRENDERSTATE_STENCILPASS, D3DSTENCILOP_REPLACE);
第二个传入的参数是来自D3DSTENCILOP列举型态。
贴图透视状态
您可以在贴图时应用透视校正,这样做适用于当基本形状逐渐远离观察者时,会不断变小的情况。您必须打开透视校正以使用w式烟雾和w缓冲。
默认值是TRUE,意谓着透视校正贴图对映功能已启动。同时,现有的大部分显示卡会自动套用透视校正。
D3DRENDERSTATE_TEXTUREPERSPECTIVE绘制状态可以用在这里,如下:
//启动贴图透视。
lpD3DDevice7->SetRenderState(D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE);
贴图方式状态
从D3DRENDERSTATE_WRAP0到D3DRENDERSTATE_WRAP7绘制状态都是针对装置的多贴图cascade中的各种贴图,用来打开和关闭u-包覆和v-包覆。
这些状态让您可以从贴图的第一、第二、第三、第四个方向启动包覆。您可以设定这些绘制状态的值为D3DWRAPCOORD_0、D3DWRAPCOORD_1、D3DWRAPCOORD_2和D3DWRAPCOORD_3旗标值的组合。如果您的设定值为0,包覆会完全关掉,但是预设的情形下,在所有贴图阶段的所有方向贴图包覆都是关闭的。 以下的程序片段说明了设定贴图包覆状态的呼叫方式:
//
//在第一个texcoords集合中设定二种坐标的包覆旗标: //
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_WRAP0,
D3DWRAPCOORD_0|D3DWRAPCOORD_1 );
顶点色彩打光状态
这种弹性的顶点格式允许顶点同时含有顶点色彩和顶点法向量信息。Direct3D的默认值是会在计算打光时用到这些信息:
//
//关掉顶点打光。 //
lpDev7->SetRenderState(D3DRENDERSTATE_COLORVERTEX,FALSE);
如果您希望您的程序不要使用顶点色彩打光信息,可呼叫
IDirect3DDevice7::SetRenderState方法,用D3DRENDER-STATE_COLORVERTEX作为第一个参数,第二个参数则设为FALSE。这样设定可以让输出alpha值等于散射材质的alpha值,固定落在0到255的范围间。如果第二个参数值为TRUE且指定某个散射顶点色彩,则输出alpha值会等于让顶点的散射alpha值。
z偏移状态
有了z偏移(z-biasing),Direct3D允许您将某个绘图页放置在另一页的前面,实时是这二个绘图页的深度值相同。您可以运用这种技巧来产生如阴影的效果。在阴影上应用z偏移时,您可以让阴影适度显示(出现在墙上),即使是阴影和墙的深度值相同。以下的程序片段中将dwRenderState设为12,有效值则是0到16:
//
//使用z偏移 //
lpDev7->SetRenderState(D3DRENDERSTATE_ZBIAS,12);
设定较高的z偏移,会让您的多边形在和其它共平面的多边形同时显示时,较可能看得清楚。
内插元素(interpolant):Gouraud上色和直射打光
在Direct3D中,Gouraud上色技巧和其它上色技巧一样,都是定义打光作业如何在顶点间内插。打光技巧(例如直射打光(specular lighting))则是用来将从对象到观察者眼中的向量并入打光计算中。因此,除非您使用平面上色,Direct3D会绘制某个面时,将三角形的顶点特征内插在三角形中。三角形内插元素是色彩、直接照射、烟雾和alpha。虽然看起来贴图坐标也是内插元素,实际上他们不会受上色模型所影响。( 第八章 会详细讨论贴图坐标)
目前的上色模式(基本形状使用的绘制模式)会修改三角形内插元素。如果您正在用平面上色,Direct3D不会执行内插;绘制器会在三角形第一个顶点的色彩应用在整个面上。如果您改用Gouraud上色,Direct3D会使用全部三个三角形顶点来执行线性内插。最后一种上色模式Phong上色(Phong shading,目前市面上的硬件都还无法支持)则是计算每个像素的色彩和打光。只要合适的硬件出现时,Direct3D就可以支持这项功能。
要注意的是色彩和直接照射内插元素在处理作法上是不同的,情况视所用的色彩模型而定。如果您用的是RGB色彩模型,Direct3D会在内插中使用红、绿和蓝色成分。如果您用的是单色(ramp)模型(在DirectX 7中已废止),Direct3D只用顶点色彩中的蓝色成分。色彩的alpha成分(负责控制色彩透明度的成分)则是作为单独的内插元素,因为装置驱动程序会用二种不同的方式产生透明效果:混合贴图(texture blending)或网点(stippling)。 要决定目前的驱动程序支持哪一种内插方式,请检查D3DPRIMCAPS结构的
dwShadeCaps成员。Direct3D会假定当支持某种基本形状时,至少D3DSHADE_FLAT模式(在D3DSHADEMODE列举型态中有定义)是可用的。 dwShadeCaps成员可以包含以下任一种或多种的旗标:
? D3DPSHADECAPS_ALPHAFLATBLEND和D3DPSHADE-CAPS_ALPHAFLATSTIPPLED 表示装置可以分别支持用alpha元素作平面混合及平面网点(D3DSHADE_FLAT状态在D3DSHADEMODE列举型态中已定义)。应用程序会提供基本形状的alpha色彩成分作为基本形状的第一个顶点的部分色彩。
? D3DPSHADECAPS_ALPHAGOURAUDBLEND和D3DP-SHADECAPS_ALPHAGOURAUDSTIPPLED 表示装置可以分别支持用alpha成分作Gouraud混合及Gouraud网点透明 (D3DSHADE_GOURAUD状态在D3DSHADEMODE列举型态中已定义)。应用程序会提供给基本形状在该顶点的alpha色彩值,而装置会沿平面内插alpha值以及其它的色彩成分。
? D3DPSHADECAPS_COLORFLATMONO和
D3DPSHADECAPS_COLORFLATRGB 表示装置可以分别支持
D3DCOLOR_MONO和D3DCOLOR_RGB模式下的彩色平面上色。在这些模式中,应用程序会提供基本形状的色彩成分作为基本形状中第一个顶点的部分色彩。如果您用的是单色打光模式,驱动程序只会内插色彩中的蓝色成分。如果您使用RGB打光模式,则红,绿,蓝三种成分都会被内插。
? D3DPSHADECAPS_COLORGOURAUDMONO和
D3DPSHADECAPS_COLORGOURAUDRGB 表示装置可以分别支持
D3DCOLOR_MONO和D3DCOLOR_RGB模式下的彩色Gouraud上色。在这些模式中,应用程序会提供基本形状中该顶点的彩色成分,而驱动程序会沿平面内插彩色成分。在单色打光模式下,驱动程序只会内插色彩中的蓝色成分。如果您使用RGB打光模式,则红,绿,蓝三种成分都会被内插。
? D3DPSHADECAPS_FOGFLAT和D3DPSHADECAPS_FOGGOURAUD 表示装置
可以分别支持平面和Gouraud上色模型中的烟雾。
? D3DPSHADECAPS_SPECULARFLATMONO和D3DP-SHADECAPS_SPECULARFLATRGB 表示装置可以分别支持
D3DCOLOR_MONO和D3DCOLOR_RGB模式下平面上色中的直接照射聚光。
? D3DPSHADECAPS_SPECULARGOURAUDMONO和
D3DPSHADECAPS_SPECULARGOURAUDRGB 表示装置可以分别支持D3DCOLOR_MONO和D3DCOLOR_RGB模式下Gouraud上色中的直接照射聚光。
建立一个3D应用程序
现在您已经学会了3D基本形状的基础,而且可以用绘制状态来影响基本形状的绘制,让我们实际来看一个绘制了有趣内容的程序!本章的RoadRage程序会比前几章来得长些,但是您应该能够了解所用的步骤。下面列出RoadRage中除了在前几章谈过的初始化作业和Windows原始码之外的动作。
加载模型