|
|
1. 什么是模板缓冲?
模板缓冲允许你'隐藏'每个点的渲染.你首先要确定使用z缓冲的位深度- 16, 24 or 32.当使用24bit 模式时有8bits未用内存,它正好用来存储模板缓冲的数据.
在 D3D8有两种格式 - 24bit Z 和 8bit 模板缓冲或 24bit Z 和 4bit 模板缓冲 (4bits未用).
我们使用模板缓冲要知道一个重要的方程
(StencilRef And StencilMask) CompFunc (StencilBufferValue And StencilMask)
方程中有四项:
1. StencilRef - 进行比较的参考数值
2. StencilMask - 掩模
3. CompFunc - 这个过程定义了每个像数如何通过模板缓冲
4. StencilBufferValue - 模板缓冲当前存储的数据
前三项可在 Direct3DDevice8.SetRenderState( ) 中设置.
模板缓冲可以建立非常高级的特效——阴影,反射...
模板深度表示屏幕上每个像数被重绘的次数。它是进行z缓冲的结果.下面是一个简单的例子:
首先,枚举可支持的模板缓冲
If D3D.CheckDepthStencilMatch(0, D3DDEVTYPE_HAL, _
DispMode.Format, DispMode.Format, _
D3DFMT_D24S8) = D3D_OK Then
'我们使用 D24/S8格式
D3DWindow.AutoDepthStencilFormat = D3DFMT_D24S8
下面代码显示了如何配置模板缓冲通道
Private Sub SetupStencilBuffer()
With D3DDevice
.SetRenderState D3DRS_STENCILENABLE, 1
.SetRenderState D3DRS_STENCILFUNC, D3DCMP_ALWAYS
.SetRenderState D3DRS_STENCILREF, 0
.SetRenderState D3DRS_STENCILMASK, 0
.SetRenderState D3DRS_STENCILWRITEMASK, &HFFFFFFFF
.SetRenderState D3DRS_STENCILZFAIL, D3DSTENCILOP_INCRSAT
.SetRenderState D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP
.SetRenderState D3DRS_STENCILPASS, D3DSTENCILOP_INCRSAT
End With
End Sub
前两行声明了开起模板缓冲功能。设置测试比较为总是通过D3DCMP_ALWAYS,不论模板缓冲存储的数据是否大于或小于参考值STENCILREF。这样掩模STENCILMASK的值也无所谓。最后一行表示测试通过的话模板深度加1。
我们现在可以用各种颜色来渲染出模板深度,它表示每像数绘制了几次。现在不需要写入操作了, .SetRenderState D3DRS_STENCILPASS, D3DSTENCILOP_KEEP用来保持模板深度的数据。.SetRenderState D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL表示进行不等于的比较操作
Private Sub RenderOverDraw()
Dim TLVerts(0 To 3) As TLVERTEX
'//needed to size the quad properly.
Dim VP As D3DVIEWPORT8
D3DDevice.GetViewport VP
'//set up the default parameters for the TL Quad. The colour will
'//be altered for each level we draw.
TLVerts(0).rhw = 1: TLVerts(1).rhw = 1: TLVerts(2).rhw = 1: TLVerts(3).rhw = 1
TLVerts(0).Color = D3DColorXRGB(255, 0, 0)
TLVerts(1).Color = TLVerts(0).Color
TLVerts(2).Color = TLVerts(0).Color
TLVerts(3).Color = TLVerts(0).Color
TLVerts(0).X = 0: TLVerts(0).Y = 0
TLVerts(1).X = VP.Width: TLVerts(1).Y = 0
TLVerts(2).X = 0: TLVerts(2).Y = VP.Height
TLVerts(3).X = VP.Width: TLVerts(3).Y = VP.Height
D3DDevice.SetTexture 0, Nothing
D3DDevice.SetVertexShader FVF_TLVERTEX
'//This next line is necessary to clear any pixels with
'//a 0 overdraw value... as they wont be picked up in the next
'//stage.
D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, 0, 0, 0
With D3DDevice
If bWire Then .SetRenderState D3DRS_FILLMODE, D3DFILL_SOLID
'//we dont care whats in the z buffer, so ignore it.
.SetRenderState D3DRS_ZENABLE, 0
.SetRenderState D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP
.SetRenderState D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP
.SetRenderState D3DRS_STENCILPASS, D3DSTENCILOP_KEEP
.SetRenderState D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL
.SetRenderState D3DRS_STENCILREF, 0
'DRAW LEVEL 1 OVERDRAW
.SetRenderState D3DRS_STENCILMASK, &H1
TLVerts(0).Color = D3DColorXRGB(0, 0, 255)
TLVerts(1).Color = TLVerts(0).Color
TLVerts(2).Color = TLVerts(0).Color
TLVerts(3).Color = TLVerts(0).Color
.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, TLVerts(0), Len(TLVerts(0))
'DRAW LEVEL 2 OVERDRAW
.SetRenderState D3DRS_STENCILMASK, &H2
TLVerts(0).Color = D3DColorXRGB(0, 255, 0)
TLVerts(1).Color = TLVerts(0).Color
TLVerts(2).Color = TLVerts(0).Color
TLVerts(3).Color = TLVerts(0).Color
.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, TLVerts(0), Len(TLVerts(0))
'DRAW LEVEL 3 OVERDRAW
.SetRenderState D3DRS_STENCILMASK, &H4
TLVerts(0).Color = D3DColorXRGB(255, 128, 0)
TLVerts(1).Color = TLVerts(0).Color
TLVerts(2).Color = TLVerts(0).Color
TLVerts(3).Color = TLVerts(0).Color
.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, TLVerts(0), Len(TLVerts(0))
...
'restore the various stage states...
.SetRenderState D3DRS_ZENABLE, 1
.SetRenderState D3DRS_STENCILENABLE, 0
End With
End Sub
每次渲染改变掩模的值(1st, 2nd, 3rd and 4th...次方),比如某一像数存储的数据为1,既它先前只绘制过一次,在第一次兰色渲染时掩模为&H1,参考值为0,方程(&H0 and &H1)<>( &H1and &H1)为真,通过测试,第2次绿色渲染时掩模为&H2,方程(&H0 and &H2)<>( &H1and &H2)为假,测试失败
|
|