默认情况下,对象是从前到后绘制的。我正在绘制一个二维UI对象,并希望将其创建回到前面。例如,我可以先创建一个白色正方形,然后在它上面创建一个略小的黑色正方形,从而创建一个带有白色边框的黑色窗格。 这篇文章对此进行了一些讨论,并将此顺序描述为“画家的算法“但最终他们提供的示例只是以相反的顺序渲染对象以获得所需的效果。我想回到前面(第一个物体进入后面,随后的物体在上面绘制)渲染可以通过一些转换来实现(gOrtho?)?

我还要提到我对使用包装库(如GLUT)的解决方案不感兴趣。

我还发现使用Cocoa NSOpenGLView的Mac上的默认行为似乎是回到前面,而在windows中我无法得到这种行为。我正在使用的Windows中的设置代码是:

glViewport (0, 0, wd, ht);
glMatrixMode(GL_PROJECTION);           
glLoadIdentity();                      
glOrtho (0.0f, wd, ht, 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);             
glLoadIdentity();                       
有帮助吗?

解决方案

以下调用将关闭深度测试,导致按创建的顺序绘制对象。这实际上会导致对象退回到前面。

glDepthFunc(GL_NEVER);      // Ignore depth values (Z) to cause drawing bottom to top

请务必不要这样说:

glEnable (GL_DEPTH_TEST);   // Enables Depth Testing

其他提示

对于您的具体问题,没有标准的方法来指定OpenGL中的深度排序。默认情况下,某些实现可能会进行前后深度排序,因为它通常更快,但不能保证(如您所发现的那样)。

但我真的不知道它会如何帮助你。如果你在白色正方形前面画一个黑色正方形,那么只要你启用了深度缓冲,就应该在白色正方形前面绘制黑色正方形,无论它们被绘制的顺序如何。如果它们实际上是共面的,那么任何一个都不会真正在另一个之前,并且任何深度排序算法都是不可预测的。

您发布链接的教程只讨论过它,因为当您使用透明度时,深度排序是相关的。但这听起来不像是你所追求的。

但如果你真的必须这样做,那么你必须自己做。首先将白色方块发送到渲染管道,强制渲染,然后发送黑色方块。如果你这样做,并禁用深度缓冲,那么方块可以是共面的,你仍然可以保证黑色方块被绘制在白色方块上。

绘图顺序很难。没有简单的解决方案。画家的算法(根据他们与相机视图的距离对物体进行排序)是最直接的,但正如您所发现的,它并不能解决所有情况。

我建议将画家的algroithm和图层组合起来。您为程序中的特定元素构建图层。所以你有一个背景图层,对象图层,特殊效果图层和GUI图层。

在每个图层的项目上使用画家的算法。在某些特殊图层(如GUI图层)中,不要使用画家的算法排序,而是按照您的调用顺序排序。你先调用那个白色方块,然后先画出它。

将您想要的项目略微放在您想要位于前面的项目后面。也就是说,实际上改变z值(假设z垂直于屏幕平面)。您不必为了让物品在彼此面前绘制而进行大量更改。如果你只是略微改变z值,你不应该注意到它们所需位置的偏移。您甚至可以非常喜欢,并根据更改的z位置计算正确的x,y位置,以便项目显示在应该位于的位置。

你的东西将按你调用glBegin / glEnd函数的确切顺序绘制。你可以使用z-buffer获得深度缓冲,如果你的2d对象有不同的z值,你可以得到你想要的效果那样。您在Mac上看到的行为的唯一方法是,程序是手动以后向前的顺序绘制内容还是使用z-buffer来完成此操作。 OpenGL否则没有你所描述的任何功能。

正如AlanKley所指出的,这样做的方法是禁用深度缓冲区。画家的算法实际上是一种2D扫描转换技术,用于在没有类似z缓冲区的情况下以正确的顺序渲染多边形。但是你不会将它应用于3D多边形。您通常会对它们进行变换和投影(处理与其他多边形的交点),然后按照投影的z坐标对生成的2D投影多边形列表进行排序,然后以反向z顺序绘制它们。

当你不能(或者不想)使用z缓冲区时,我一直认为画家的算法是隐藏表面去除的替代技术。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top