Gam*_*per 5 opengl stencil-buffer
OpenGL 参考 pdf 中的文档(OpenGL 3.3 和 4.5 规范)对于应用遮罩时存储的模板值会发生什么情况不太清楚。
例如如果我有以下掩码:
glStencilMask( 0x06);
Run Code Online (Sandbox Code Playgroud)
并且存储在模板缓冲区中已经有这个值:
0x06
Run Code Online (Sandbox Code Playgroud)
如果模板操作是GL_INCR_WRAP
当在该像素上正确调用 StencilOp 时会发生什么?
基本上我有面具:
00000110
Run Code Online (Sandbox Code Playgroud)
和价值
00000110
Run Code Online (Sandbox Code Playgroud)
我尝试增加它,它被包裹了吗?
00000010
Run Code Online (Sandbox Code Playgroud)
或者只是归零?(00000110 + 1) & mask
00000000
Run Code Online (Sandbox Code Playgroud)
OpenGL 4.5 核心配置文件规范的第 17.4.2 节“缓冲区更新的精细控制”指出:
这些命令
void StencilMask( uint mask );void StencilMaskSeparate( enum face, uint mask );控制将特定位写入模板平面。的最低有效 s 位mask(其中 s 是模板缓冲区中的位数)指定整数掩码。当此掩码中出现 1 时,将写入模板缓冲区中的相应位;如果出现 0,则表示该位未被写入。
该glStencilMask()参数控制将哪些位平面写入模板缓冲区。它不控制读取的内容或glStencilOp操作方式。
第 17.3.5 节“模板测试”指出(我的重点):
为了递增和递减的目的,模板位被视为无符号整数。通过饱和度递增或递减会将模板值限制在 0 和最大可表示值。在不饱和的情况下递增或递减将换行,这样递增最大可表示值会导致 0,递减 0 会导致最大可表示值。
模板掩模本身与管道的该阶段无关。与所有函数一样,它仅在片段最终写入帧缓冲区时应用gl*Mask()。
因此,将值0110放入缓冲区并应用GL_INCR_WRAP会导致0111当将其写入缓冲区时,会应用掩码,因此基本上会再次得到0110(而不是 0)。
另请注意,还有一个mask参数用于glStencilFunc()定义在模板测试之前应用的位掩码。再次引用17.3.5节:(我的重点):
StencilFunc并StencilFuncSeparate采用三个参数来控制模板测试是否通过。ref是用于无符号模板比较的整数参考值。模板比较操作和查询将ref其值限制在范围 [0; 2^s - 1],其中 s 是附加到绘制帧缓冲区的模板缓冲区中的位数。的最低有效位mask与参考值和存储的模板值进行按位与运算,所得掩码值是参与由 控制的比较的值func。
因此,如果您想将 a 环绕为某个值 2^n-1,您可以简单地忽略模板缓冲区中的附加位,并仅在模板测试中测试这些位。