我正在尝试在给定链接http://commons.wikimedia.org/wiki/File:OpenGL_Tutorial_Stencil.png中描述的OpenGL中实现以下效果,代码片段也在下面,这是官方的openGL维基百科教程。
虽然它有代码并注释掉解释但我仍然觉得很难理解openGL中模板缓冲区操作的逻辑。我提醒一下,在开始模板印刷之前,我阅读了红皮书中的大部分说明,所以我知道并且我很熟悉,glStencilFunc,glStencilOp和glStencilMask等工作原理,但是仍有一些模糊不清的东西在我的想法与模板有关。
以下是我如何解释代码的演练:
使用glStencilFunc(GL_NEVER, 1, 0xFF); glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
我认为模板测试将始终通过,模板测试失败将导致模板缓冲区中的1s填充,因为glStencilOp
如果前面的代码块(#1)设置了模板缓冲区中的所有像素,那么我们使用glStencilMask(0xFF);
过程调用实现了这一点。我们是否保证所有1都成功写入模板缓冲区或实际上是什么?
我们绘制圆圈然后打开蒙版,但这次glStencilMask(0x00)
,这是一个混乱,我认为这涉及防止模板缓冲区值被新值覆盖,但代码注释说这只是用0来填充模板缓冲区。
最后,如果我们不在模板缓冲区中更改任何值(由于glStencilMask(0x00)
),那么有什么意义
// fill 0s
glStencilFunc(GL_EQUAL, 0, 0xFF);
/* (nothing to draw) */
// fill 1s
glStencilFunc(GL_EQUAL, 1, 0xFF);
主要计划机构:
void onDisplay() {
glClearColor(0.1, 0.1, 0.1, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
glStencilFunc(GL_NEVER, 1, 0xFF);
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); // draw 1s on test fail (always)
// draw stencil pattern
glStencilMask(0xFF);
glClear(GL_STENCIL_BUFFER_BIT); // needs mask=0xFF
draw_circle();
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
glStencilMask(0x00);
// fill 0s
glStencilFunc(GL_EQUAL, 0, 0xFF);
/* (nothing to draw) */
// fill 1s
glStencilFunc(GL_EQUAL, 1, 0xFF);
draw_scene();
glDisable(GL_STENCIL_TEST);
glutSwapBuffers();
}
答案 0 :(得分:1)
glStencilMask(0xFF)
类似于glColorMask(true, true, true, true)
或glDepthMask(true)
函数 - 0xFF是一个掩码,在将其写入模板缓冲区之前,它与任何模板数据进行逐位AND运算。因此,通过glStencilMask(0xFF)
,我们确保成功写入OpenGL尝试写入模板缓冲区的任何值。
glStencilMask(0x00)
:当0x00与任何字节按位进行AND运算时,输出将始终为0.因此,任何时候尝试将字节写入模板缓冲区,写入的字节将为0.实际上,此时,它只是确保模板缓冲区没有写入任何新数据。
根据我的解释,带有/* (nothing to draw) */
注释的部分是您在模板测试圆圈外绘制的材料的地方。 0是模板缓冲区中的默认值。因此,由于圆圈中的区域标记为1,因此圆圈外的像素将通过,并且内部的像素将被丢弃。它只是一个占位符。
我相信当评论说// fill 0s
时,他们的意思是“这里绘制的任何内容都将填充设置为0的模板缓冲区的部分。考虑到调用glStencilFunc
以GL_EQUAL
和0
作为参数,这就是将要发生的事情。我也相信,当评论说// fill 1s
时,它们的意思相同,但部分是模板缓冲区设置为1(即圆圈已被绘制到模板缓冲区的区域。)