模具缓冲区技术 (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))

像素管道