OpenGL参考pdf(OpenGL 3.3和4.5规范)中的文档对于应用掩码时存储的模板值会发生什么情况并不十分清楚。
在示例中如果我有以下掩码:
glStencilMask( 0x06);
并存储在模板缓冲区中,已存在此值:
0x06
如果模板操作为GL_INCR_WRAP
在该像素上正确调用StencilOp时会发生什么?
基本上我有面具:
00000110
和值
00000110
我尝试增加它,它被包裹了吗?
00000010
还是刚刚归零? (00000110 + 1) & mask
00000000
答案 0 :(得分:3)
第17.4.2节"缓冲更新的精细控制" OpenGL 4.5 core profile specification个州:
命令
void StencilMask( uint mask );
void StencilMaskSeparate( enum face, uint mask );
控制特定位写入模板平面。mask
的最低有效位,其中s是模板缓冲区中的位数,指定整数掩码。如果该掩码中出现1,则写入模板缓冲区中的相应位;如果出现0,则不写入该位。
glStencilMask()
参数控制哪些位平面写入到模板缓冲区。它不控制读取内容或glStencilOp
如何操作。
第17.3.5节"模板测试"国家(我的重点):
为了递增和递减,模板位被认为是 无符号整数。通过饱和度递增或递减钳位模板 值为0和最大可表示值。递增或递减而不饱和将换行,使得递增最大可表示值导致0 ,递减0导致最大可表示值。
模板掩模本身与管道的那个阶段无关。它仅在最终将片段写入帧缓冲区时应用,与所有gl*Mask()
函数一样。
因此,在缓冲区中使用值0110
并应用GL_INCR_WRAP
会导致0111
,并且当写入缓冲区时,将应用掩码,因此您基本上会以{{ 1}}再次(而不是0)。
另请注意,0110
中还有一个mask
参数,用于定义在模板测试之前应用的位掩码。再次引用第17.3.5节:(我的重点):
glStencilFunc()
和StencilFunc
采用三个控制的参数 模板测试是否通过。StencilFuncSeparate
是整数引用值,用于无符号模板比较。模板比较操作和ref
的查询将其值限制在范围[0; 2 ^ s - 1],其中s是附加到绘制帧缓冲区的模板缓冲区中的位数。ref
的最低位 与参考值和存储的模板值进行按位AND运算,得到的掩码值是参与由mask
控制的比较的值。
因此,如果你想绕过一个2 ^ n-1的值,你可以简单地忽略模板缓冲区中的附加位,并在模板测试中测试这些位。