模具缓冲区技术 (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 将执行操作。 测试执行步骤如下。

  1. 用模具掩码执行模具参考值的按位 AND 运算。
  2. 用模具掩码执行当前像素的模板缓冲区值的按位 AND 运算。
  3. 使用比较函数,对比第 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))

像素管道