opengl-es - OpenGL ES:模板缓冲区和剔除
问题描述
我是 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
有人可以帮我理解为什么前后模板缓冲区似乎与剔除模式交换了吗?
解决方案
听起来您认为有两种不同的模板缓冲区,一种用于正面,一种用于背面。这是不正确的;只有一个模板缓冲区,每个像素有一个模板值。
这些glSeparate...()
函数只是为您提供了为正面和背面三角形指定单独的模板测试/更新规则的方法,但它们将写入帧缓冲区中的相同存储位置。
假设您有一个正面最靠近相机的立方体,那么在您第一次通过后“幸存”的模板值将始终是正面参考值。
更新:请注意,您可以在同一模板缓冲区中“混合”正面和背面模板值,方法是使用 glStencilMaskSeparate()
来控制可以写入的位,并glStencilFuncSeparate()
控制在模板测试时使用哪些位。
推荐阅读
- java - ForkJoinPool 和查询的并行执行
- node.js - 图像在某些页面上显示但在其他页面上不显示的问题
- javascript - 如何以适当的方式在Javascript中对给定数组执行crud操作
- android - Google Play 内部应用共享不再适用于任何设备
- jmeter - 使用终极线程组时JMeter频率峰值
- spring - 如何使用 Thymeleaf 从外部文件夹加载模板
- ms-word - 有没有办法防止在 OpenOffice 中编辑 MS docx 文档?
- javascript - 如何通过模型显示在 ajax 请求中传递动态 url?
- c# - 如何用从另一个类(第 3 类)传递给一个类(第 2 类)的对象填充列表?
- python - 为什么类中名为节点的列表变量会获取类的前一个实例的输出?