如何确保从一个GL程序渲染覆盖其他程序的渲染?

时间:2016-02-17 08:13:26

标签: android opengl-es 3d

我在使用Open GL ES 2.0的Android Studio中工作。

每次渲染视图时,我都会使用两个GL程序。他们有不同的着色器。 现在碰巧我在程序中绘制的对象重叠。我的问题是,当他们重叠对象时,我想要在另一个对象的后面。我想要的基本上是program2绘制的对象始终可见,而另一个对象就像在背景中一样,当它们重叠时,它就在另一个之后。

我怎样才能确定?我无法禁用深度测试,因为我绘制的对象需要它。

3 个答案:

答案 0 :(得分:0)

OpenGL并不关心你的对象结构。由于它只处理三角形,因此在启用时将对所有内容进行深度测试。

我唯一想到的是将两个对象渲染为单独的fbos(启用深度测试),然后按照您希望对象的顺序组合它们(不进行深度测试)。请注意,当您拥有大量此类对象时,这将无法很好地扩展。

答案 1 :(得分:0)

该计划与此无关。但是在渲染两个对象的基本问题上,在每个对象内进行适当的深度测试,但是一个对象完全在另一个对象的前面,至少有两种简单的方法。

两次清除深度缓冲区

一种方法是首先渲染背景对象,然后清除深度缓冲区,然后渲染前景对象:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw first ("background") object.
glClear(GL_DEPTH_BUFFER_BIT);
// Draw second ("foreground") object.

请注意,只有第二次glClear()调用才会清除深度缓冲区。因此将显示两个对象。但是,由于在绘制第二个对象之前清除了深度缓冲区,因此第一个对象不会遮挡第二个对象。

使用深度范围

另一种方法是为每个对象使用不同的深度范围。默认情况下,深度范围为[0.0,1.0],这意味着可见深度范围将映射到整个深度值范围。但你可以改变这一点。以你的例子:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthRangef(0.5f, 1.0f);
// Draw first ("background") object.
glDepthRangef(0.0f, 0.5f);
// Draw second ("foreground") object.
glDepthRange(0.0f, 1.0f);

现在,这两个对象被映射到整个深度范围的不同子范围。第一个对象将映射到介于0.5和1.0之间的深度值,而第二个对象将映射到介于0.0和0.5之间的深度值。因此,第二个对象的所有深度值都将小于第一个对象的深度值,这意​​味着深度测试将认为第二个对象完全位于第一个对象的前面。

答案 2 :(得分:0)

虽然有可能实现这个结果的方法(已经发布了2个)但我会说这是模板缓冲区的工作。

具有优先级(始终位于前面)的渲染还必须绘制到模板缓冲区。然后,其他程序必须丢弃使用模板测试绘制模板缓冲区的片段。

模板缓冲区很像深度缓冲区,但实际上并不绑定深度(片段的z值)。您可以设置与深度缓冲区相同的测试,并且我已经看到一些实现,您甚至可以在与深度相同的缓冲区上使用它,因此您有24位深度和8位用于模板。因此,对于8位模板缓冲区,您可以实际使用256个绘图程序,然后按照优先顺序排列。

因此,您可以通过更改深度范围或任何性能问题来避免深度精度损失,就像使用多个FBO然后将它们合并在一起一样。