Opengl es OpenGL ES:模具缓冲区和剔除

Opengl es OpenGL ES:模具缓冲区和剔除,opengl-es,pyopengl,stencil-buffer,Opengl Es,Pyopengl,Stencil Buffer,我是OpenGL新手,我正在尝试一些实验,尤其是模具缓冲区。 在我的代码中,我分别使用glStencilFuncSeparate将前后模具缓冲区设置为0x5和0xC(GL_始终作为函数的参数)。glStencilOpSeparate为dppass的前后状态设置为GLU REPLACE。我还确保在设置两个模具缓冲区时禁用深度和剔除 接下来,我尝试渲染一个启用了深度、前消隐和模具测试的立方体。我现在使用glStencilFuncSeparate()通过与0x12进行比较,仅绘制背面模具设置区域。由于

我是OpenGL新手,我正在尝试一些实验,尤其是模具缓冲区。 在我的代码中,我分别使用glStencilFuncSeparate将前后模具缓冲区设置为0x5和0xC(GL_始终作为函数的参数)。glStencilOpSeparate为dppass的前后状态设置为GLU REPLACE。我还确保在设置两个模具缓冲区时禁用深度和剔除

接下来,我尝试渲染一个启用了深度、前消隐和模具测试的立方体。我现在使用glStencilFuncSeparate()通过与0x12进行比较,仅绘制背面模具设置区域。由于正面被剔除,我希望只显示值为0x12的背面模具缓冲区覆盖的区域

但令我沮丧的是,它显示的是空白屏幕。当它将比较值设置为0x5(前模具初始值)并将cull face设置为front时,我可以看到立方体的部分

因此,它似乎表明,当culling设置为GL_front时,立方体的背面将与前模具进行比较。所有其他参数,如StencilClear(值0x1)看起来都是正确的,我无法理解这种行为

设置模具 启用剔除 画一个立方体 OpenGL版本:OpenGL ES 3.1 Mesa 19.0.8,Mesa DRI英特尔Haswell桌面


有人能帮我理解为什么前后模具缓冲区似乎是用剔除模式交换的吗?

听起来好像你认为有两种不同的模具缓冲区,一种用于正面,另一种用于背面。这是错误的;只有一个模具缓冲区,每个像素有一个模具值

glSeparate…()
函数只提供了为正面和背面三角形指定单独模具测试/更新规则的方法,但它们将写入帧缓冲区中的相同存储位置

如果您有一个正面最靠近相机的立方体,那么第一次通过后的“幸存”模具值始终将是正面参考值


更新:请注意,您可以在同一模具缓冲区中“混合”前后模具值,方法是使用
glStencilMaskSeparate()
控制可以写入哪些位,以及
glStencilFuncSeparate()
控制模具测试时使用哪些位。

感谢您的澄清。真的很有帮助。但我仍然不明白的是,在绘制反刍动物之前,我确实会调用glCullFace(GL_FRONT)。那么正面将如何成为幸存的模具值。在创建模具遮罩时,您没有启用面剔除,因此模具缓冲区将只包含正面模具值(0x5)。在第二个过程中,与0xC的比较总是会失败。未看到正面(因为正面测试失败)。未看到背面(因为无法与0xC进行比较)。结果=空白屏幕。实际上,您提到在创建模具掩码时禁用深度测试,因此模具缓冲区中的最终结果将取决于原始顺序;写在最后的都是“赢”。
glStencilMaskSeparate(GL_FRONT_AND_BACK, 0xff)
glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0x5, 0xff)
glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0xc, 0xff)
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_REPLACE)
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_REPLACE)
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)
glDepthMask(GL_FALSE)
glDrawArrays(GL_TRIANGLES, 0, 6)
glCullFace(GL_FRONT)
glEnable(GL_CULL_FACE)
glStencilOpSeparate(GL_FRONT,GL_KEEP,GL_KEEP,GL_REPLACE)
glStencilOpSeparate(GL_BACK,GL_KEEP,GL_KEEP,GL_REPLACE)
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)
glDepthMask(GL_FALSE)
glDrawArrays(GL_TRIANGLES, 0, 36)