【问题标题】:How does mask affect stencil value according to stencil op?根据模板操作,掩码如何影响模板值?
【发布时间】:2015-09-29 13:19:06
【问题描述】:

OpenGL 参考 pdf(OpenGL 3.3 和 4.5 规范)中的文档对于应用遮罩时存储的模板值会发生什么情况并不太清楚。

例如,如果我有以下掩码:

glStencilMask( 0x06);

并且存储在模板缓冲区中已经有这个值了:

0x06

如果模板操作是GL_INCR_WRAP

在该像素上正确调用 StencilOp 时会发生什么?

基本上我有面具:

00000110

和价值

00000110

我尝试增加它,它被包裹了吗?

00000010

还是只是归零? (00000110 + 1) & mask

00000000

【问题讨论】:

    标签: opengl stencil-buffer


    【解决方案1】:

    OpenGL 4.5 core profile specification 的第 17.4.2 节“缓冲区更新的精细控制”指出:

    命令 void StencilMask( uint mask ); void StencilMaskSeparate( enum face, uint mask ); 控制将特定位写入模板平面。 mask 的最低有效 s 位,其中 s 是模板缓冲区中的位数,指定一个整数掩码。在此掩码中出现 1 时,写入模板缓冲区中的相应位;出现 0 时,不写入该位。

    glStencilMask() 参数控制将哪些位平面写入 到模板缓冲区。它不控制读取的内容或glStencilOp 的操作方式。

    第 17.3.5 节“模板测试”状态(我的重点):

    出于递增和递减的目的,模板位被视为 无符号整数。饱和度递增或递减会夹住模板 值 0 和最大可表示值。在不饱和的情况下递增或递减将换行,使最大可表示值递增导致 0,而递减 0 导致最大可表示值。

    模板掩码本身与流水线的那个阶段无关。它仅在片段最终写入帧缓冲区时应用,就像所有 gl*Mask() 函数一样。

    因此,在缓冲区中有值 0110 并应用 GL_INCR_WRAP 会导致 0111 并且当它被写入缓冲区时,将应用掩码,所以你基本上再次以 0110 结束(而不是 0 )。

    还要注意glStencilFunc() 中还有一个mask 参数定义了在模板测试之前要应用的位掩码。再次引用第 17.3.5 节:(我的重点):

    StencilFuncStencilFuncSeparate 采用三个参数来控制 模板测试是通过还是失败。 ref 是一个整数参考值,用于无符号模板比较。 ref 的模板比较操作和查询将其值钳制在 [0; 2^s - 1],其中 s 是附加到绘图帧缓冲区的模板缓冲区中的位数。 mask 的 s 最低有效位 与参考值和存储的模板值进行按位与运算,生成的掩码值是参与由func 控制的比较的值。

    因此,如果您想在某个值 2^n-1 处环绕 a,您可以简单地忽略模板缓冲区中的附加位,并在模板测试中测试这些位。

    【讨论】:

    • 谢谢,这是一个完美的答案:) 所以基本上glStencilMask 只是在写入缓冲区之前屏蔽一个值,而glStencilFunc 的掩码仅在模板测试期间以@ 之类的方式使用987654342@
    猜你喜欢
    • 2017-09-23
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    • 2015-02-01
    • 1970-01-01
    • 2014-02-10
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多