我想到了几种可能性。
每帧多次清除深度缓冲区
最简单的方法可能是在渲染一组对象后清除深度缓冲区。对于问题中的情况:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw triangle 1.
// Draw triangle 2.
glClear(GL_DEPTH_BUFFER_BIT);
// Draw triangle 3.
// Draw triangle 4.
由于您不会在 1/2 和 3/4 之间进行深度测试,因此如果三角形 3 和 4 重叠,则三角形 3 和 4 将绘制在三角形 1 和 2 的顶部,而与它们的相对深度无关。
此解决方案的一个限制是您必须将每个组的几何图形一起绘制。例如,如果由于某种原因您按 1、3、2、4 的顺序渲染三角形,则不能使用它。
具有多个深度缓冲区的 FBO 渲染
另一种选择是使用多个深度缓冲区。做到这一点的唯一方法是使用 FBO 的离屏渲染。在这种情况下,您可以创建多个深度渲染缓冲区。在每次绘制调用之前,您可以将可以使用的深度缓冲区附加到 FBO。
完成将帧渲染到 FBO 后,您必须将内容复制到默认帧缓冲区。
这样做的好处是,只要每次切换深度缓冲区,您就可以按任何顺序绘制三角形:
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depthBuf1);
// draw triangle 1
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depthBuf2);
// draw triangle 3
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depthBuf1);
// draw triangle 2
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depthBuf2);
// draw triangle 4
但是,切换渲染缓冲区可能是一项相当昂贵的操作,因此您仍然希望尽量减少切换深度缓冲区的次数。
因此,这种方法为您提供了更大的灵活性,但我通常认为它的效率会降低。您仍然需要清除所有深度缓冲区,因此您有多个深度清除操作,就像在第一种方法中一样。此外,您还有切换深度缓冲区以及将颜色缓冲区复制到帧末尾的默认帧缓冲区的开销。