我一直在阅读OpenGL规范,试图找到这个问题的答案,但是没有成功。我想知道OpenGL是否保证像GLDrawElements或GLDrawArrays这样的绘制调用将按照它们在VBO中出现的顺序精确绘制元素,还是可以以任何顺序处理这些基本图元的片段。
例如,如果我有一个包含30个顶点的顶点缓冲区,表示10个具有相同坐标的三角形。那么对于顶点0、1和2对应的三角形,它总是被渲染在最底部;而对于顶点28、29和30对应的三角形,它总是被渲染在最顶部吗?
我一直在阅读OpenGL规范,试图找到这个问题的答案,但是没有成功。我想知道OpenGL是否保证像GLDrawElements或GLDrawArrays这样的绘制调用将按照它们在VBO中出现的顺序精确绘制元素,还是可以以任何顺序处理这些基本图元的片段。
例如,如果我有一个包含30个顶点的顶点缓冲区,表示10个具有相同坐标的三角形。那么对于顶点0、1和2对应的三角形,它总是被渲染在最底部;而对于顶点28、29和30对应的三角形,它总是被渲染在最顶部吗?
规范非常谨慎地定义了一切呈现的顺序。顶点数据的数组按顺序处理,这会导致基元以特定顺序生成。每个基元都按顺序光栅化,之后的基元在前面的基元完成之前无法光栅化。
当然,这只是OpenGL所说应该的行为。实现可以(并且也确实)通过同时光栅化和处理多个基元来作弊。但是,它们仍将遵守“好像”规则。因此,它们内部作弊,但仍然会好像按顺序全部执行完毕一样,写入结果。
因此,是的,您可以依靠特定的顺序。除非您使用执行不连贯内存访问的着色器;那么对于着色器写入,所有赌注都关闭了。
glBlendFunc(GL_ONE, GL_DST_COLOR);
如果最终帧缓冲区内容按照可绘制的图元的任意顺序写入,那么在这种情况下,您会看到类似于Z-fighting的效果。
这就是为什么它被称为片段着色器(而不是像素着色器)的原因,因为它还不是一个像素,因为在片段阶段之后它还没有被写入帧缓冲区;只有在光栅操作阶段之后才会写入。