【问题标题】:OpenGL ES: Stencilbuffers and cullingOpenGL ES:模板缓冲区和剔除
【发布时间】:2020-04-10 02:04:07
【问题描述】:

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

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

但令我沮丧的是,它显示空白屏幕。当它给出比较值为 0x5(front stencil init val) 且剔除面为正面时,我可以看到立方体的部分。

所以这似乎表明,当剔除设置为 GL_FRONT 时,立方体的背面与正面模板进行比较。 StencilClear(value 0x1) 等所有其他参数看起来都正确,但我不知何故无法理解这种行为。

设置模板

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)

OpenGL 版本:OpenGL ES 3.1 Mesa 19.0.8,Mesa DRI Intel Haswell Desktop

有人可以帮我理解为什么正面和背面模板缓冲区似乎与剔除模式交换了吗?

【问题讨论】:

    标签: opengl-es pyopengl stencil-buffer


    【解决方案1】:

    听起来您认为有两种不同的模板缓冲区,一种用于正面,一种用于背面。这是不正确的;只有一个模板缓冲区,每个像素有一个模板值。

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

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

    更新:请注意,您可以使用glStencilMaskSeparate() 控制可以写入哪些位,并使用glStencilFuncSeparate() 控制哪些位来“混合”同一模板缓冲区中的正面和背面模板值在模板测试时使用。

    【讨论】:

    • 感谢您的澄清。真的很有帮助。但我仍然没有得到的是,在绘制 cude 之前我确实调用了 glCullFace(GL_FRONT)。那么正面如何成为幸存的模板价值。
    • 创建模板蒙版时没有启用面部剔除,因此模板缓冲区只会包含正面模板值 (0x5)。在第二遍中,与 0xC 的比较总是会失败。看不到正面(因为它未能通过正面测试)。背面看不到(因为它无法与 0xC 进行比较)。结果 = 空白屏幕。
    • 实际上,您提到在创建模板掩码时禁用了深度测试,因此模板缓冲区中的最终结果将取决于原始顺序;最后写的将“获胜”。
    猜你喜欢
    • 2014-12-18
    • 2011-03-09
    • 2011-01-17
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    相关资源
    最近更新 更多