模具缓冲区技术 (Direct3D 9)
应用程序使用模具缓冲区来屏蔽图像中的像素。 掩码控制是否绘制像素。 一些较常见的效果如下所示。
模板缓冲区逐个像素地启用或禁用渲染目标图面绘制。 究其本质,它使应用程序遮罩部分渲染图像,因此这些部分不会显示。 应用程序常常使用模板缓冲区实现特殊效果,例如溶解、贴纸和轮廓描绘。
模板缓冲区信息嵌入在 z 缓冲区数据中。 应用程序可以使用 IDirect3D9::CheckDeviceFormat 方法检查硬件模具支持,如以下代码示例所示。
// Reject devices that cannot perform 8-bit stencil buffering.
// The following example assumes that pCaps is a valid pointer
// to an initialized D3DCAPS9 structure.
if( FAILED( m_pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal,
pCaps->DeviceType,
Format,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
D3DFMT_D24S8 ) ) )
return E_FAIL;
IDirect3D9::CheckDeviceFormat 允许根据该设备的功能选择要创建的设备。 在这种情况下,将拒绝不支持 8 位模具缓冲区的设备。 请注意,这只是 IDirect3D9::CheckDeviceFormat 的一种可能用途;有关详细信息,请参阅 确定硬件支持 (Direct3D 9) 。
模具缓冲区的工作原理
Direct3D 针对模板缓冲区的内容逐个像素地执行测试。 对于目标图面中的每个像素,它使用模板缓冲区中相应的值(模具参考值、模具掩码值)对其执行测试。 如果测试通过,Direct3D 将执行操作。 测试执行步骤如下。
- 用模具掩码执行模具参考值的按位 AND 运算。
- 用模具掩码执行当前像素的模板缓冲区值的按位 AND 运算。
- 使用比较函数,对比第 1 步和第 2 步的结果。
下面的代码示例中显示了这些步骤。
(StencilRef & StencilMask) CompFunc (StencilBufferValue & StencilMask)
StencilBufferValue
是当前像素的模具缓冲区的内容。 此代码示例使用和 (&) 符号来表示按位 AND 运算。
StencilMask
表示模具掩码的值,并且
StencilRef
表示模具引用值。
CompFunc
是比较函数。
如果模具测试通过,当前像素将写入目标图面,否则将忽略。 默认比较行为是写入像素,无论每个按位运算结果如何 (D3DCMP_ALWAYS) 。 可以通过更改D3DRS_STENCILFUNC呈现状态的值,传递 D3DCMPFUNC 枚举类型的成员来标识所需的比较函数来更改此行为。
你的应用程序可以自定义设置模板缓冲区的运算。 它可以设置比较函数、模具掩码和模具参考值。 它还可以控制模具测试通过或失败时 Direct3D 采取的操作。 有关详细信息,请参阅 模具缓冲区状态 (Direct3D 9) 。
示例
以下代码示例演示如何设置模具缓冲区。
// Enable stencil testing
pDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
// Specify the stencil comparison function
pDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
// Set the comparison reference value
pDevice->SetRenderState(D3DRS_STENCILREF, 0);
// Specify a stencil mask
pDevice->SetRenderState(D3DRS_STENCILMASK, 0);
默认情况下,模具引用值为零。 任何整数值都有效。 Direct3D 在模具测试之前对模具引用值和模具掩码值执行按位 AND。
可以根据模具比较来控制写出哪些像素信息。
// A write mask controls what is written
pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, D3DSTENCILOP_KEEP);
// Specify when to write stencil data
pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
可以为要写入模具缓冲区的值编写自己的公式,如以下示例所示。
NewStencilBufferValue = (StencilBufferValue & ~StencilWriteMask) |
(StencilWriteMask & StencilOp(StencilBufferValue))
相关主题