我正在尝试在给定链接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);
,模板测试失败将导致模板缓冲区填充 1 秒,因为设置的指令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();
}