我刚刚开始进入OpenGL中的遮挡查询主题,但我对它们的实际工作方式有点困惑。
在我发现的大多数示例中,在使用遮挡查询绘制之前,深度和颜色蒙版都被停用了(因为我们不需要实际"绘制"任何东西(,本质上有点像这样:
glDepthMask(GL_FALSE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glBeginQuery(GL_ANY_SAMPLES_PASSED,query1);
// Draw Object 1
glEndQuery(GL_ANY_SAMPLES_PASSED);
glBeginQuery(GL_ANY_SAMPLES_PASSED,query2);
// Draw Object 2
glEndQuery(GL_ANY_SAMPLES_PASSED);
// etc
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
(假定对象是从前到后绘制的,因此对象 1 位于对象 2 的前面。为了这个问题,上面的代码只是伪代码。稍后将检索查询的结果。
现在,要知道对象 2 是否真的被对象 1 遮挡,它需要以某种方式保留查询 1 中的片段信息(我假设在某种深度缓冲区中(。但是我们已经禁用了绘制到深度和颜色缓冲区,这意味着没有绘制任何内容,这意味着它不应该在任何地方存储任何内容?
是否有特殊的"查询"缓冲区?如果是这样,有没有办法访问它?它是否以任何方式连接到当前绑定的纹理或帧缓冲区?我需要清除它吗?我是否误解了遮挡查询的实际工作原理?
现在,要知道对象 2 是否真的被对象 1 遮挡,它需要以某种方式保留查询 1 中的片段信息。
为什么会这样?遮挡查询存储通过深度测试的样本数的计数器,该计数器为单个整数。
由于已禁用写入颜色和深度缓冲区,因此绘制对象的唯一操作就是增加遮挡查询计数器*。对象 2 不可能遮挡对象 1,因为绘制对象 1 不会更改深度缓冲区。
* 除非您有模板缓冲区或正在执行诸如在着色器中加载/存储图像之类的操作