By default it seems that objects are drawn front to back. I am drawing a 2-D UI object and would like to create it back to front. For example I could create a white square first then create a slightly smaller black square on top of it thus creating a black pane with a white border. This post had some discussion on it and described this order as the "Painter's Algorithm" but ultimately the example they gave simply rendered the objects in reverse order to get the desired effect. I figure back to front (first objects go in back, subsequent objects get draw on top) rendering can be achieved via some transformation (gOrtho?) ?
默认情况下,似乎从前到后绘制对象。我正在绘制一个二维UI对象,并希望将其创建回到前面。例如,我可以先创建一个白色正方形,然后在它上面创建一个略小的黑色正方形,从而创建一个带有白色边框的黑色窗格。这篇文章对它进行了一些讨论,并将此顺序描述为“画家的算法”,但最终他们给出的例子只是以相反的顺序渲染对象以获得所需的效果。我想回到前面(第一个物体进入后面,随后的物体在上面绘制)渲染可以通过一些变换来实现(gOrtho?)?
I will also mention that I am not interested in a solution using a wrapper library such as GLUT.
我还要提到我对使用包装库(如GLUT)的解决方案不感兴趣。
I have also found that the default behavior on the Mac using the Cocoa NSOpenGLView appears to draw back to front, where as in windows I cannot get this behavior. The setup code in windows I am using is this:
我还发现使用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();
6 个解决方案
#1
22
The following call will turn off depth testing causing objects to be drawn in the order created. This will in effect cause objects to draw back to front.
以下调用将关闭深度测试,导致按创建的顺序绘制对象。这实际上会导致对象退回到前面。
glDepthFunc(GL_NEVER); // Ignore depth values (Z) to cause drawing bottom to top
Be sure you do not call this:
请务必不要这样称呼:
glEnable (GL_DEPTH_TEST); // Enables Depth Testing
#2
5
For your specific question, no there is no standardized way to specify depth ordering in OpenGL. Some implementations may do front to back depth ordering by default because it's usually faster, but that is not guaranteed (as you discovered).
对于您的具体问题,没有标准的方法来指定OpenGL中的深度排序。默认情况下,某些实现可能会进行前后深度排序,因为它通常更快,但不能保证(如您所发现的那样)。
But I don't really see how it will help you in your scenario. If you draw a black square in front of a white square the black square should be drawn in front of the white square regardless of what order they're drawn in, as long as you have depth buffering enabled. If they're actually coplanar, then neither one is really in front of the other and any depth sorting algorithm would be unpredictable.
但我真的没有看到它会如何帮助你在你的场景中。如果你在白色正方形前面画一个黑色正方形,那么只要你启用了深度缓冲,就应该在白色正方形前面绘制黑色正方形,而不管它们绘制的顺序是什么。如果它们实际上是共面的,那么任何一个都不是真的在另一个之前,并且任何深度排序算法都是不可预测的。
The tutorial that you posted a link to only talked about it because depth sorting IS relevant when you're using transparency. But it doesn't sound to me like that's what you're after.
您发布链接的教程仅讨论了它,因为深度排序与您使用透明度时相关。但这听起来不像是你所追求的。
But if you really have to do it that way, then you have to do it yourself. First send your white square to the rendering pipeline, force the render, and then send your black square. If you do it that way, and disable depth buffering, then the squares can be coplanar and you will still be guaranteed that the black square is drawn over the white square.
但如果你真的必须这样做,那么你必须自己做。首先将白色方块发送到渲染管道,强制渲染,然后发送黑色方块。如果你这样做,并禁用深度缓冲,那么正方形可以是共面的,你仍然可以保证黑色正方形被绘制在白色正方形上。
#3
2
Drawing order is hard. There is no easy solution. The painter's alogorithm (sort objects by their distance in relation to your camera's view) is the most straightforward, but as you have discovered, it doesn't solve all cases.
绘图顺序很难。没有简单的解决方案。画家的算法(根据他们与相机视图的距离对物体进行排序)是最直接的,但正如您所发现的,它并不能解决所有情况。
I would suggest a combination of the painter's algroithm and layers. You build layers for specific elements on your program. So you got a background layer, objects layers, special effect layers, and GUI layer.
我会建议画家的alrefithm和层的组合。您为程序中的特定元素构建图层。因此,您有一个背景图层,对象图层,特殊效果图层和GUI图层。
Use the painter's algorithm on each layer's items. In some special layers (like your GUI layer), don't sort with the painter's algorithm, but by your call order. You call that white square first so it gets drawn first.
在每个图层的项目上使用画家的算法。在某些特殊图层(如GUI图层)中,不要使用画家的算法排序,而是按照您的调用顺序排序。你首先调用那个白色方块,然后先画出它。
#4
2
Draw items that you want to be in back slightly behind the items that you want to be in the front. That is, actually change the z value (assuming z is perpendicular to the screen plane). You don't have to change it a lot to get the items to draw in front of eachother. And if you only change the z value slightly, you shouldn't notice much of an offset from their desired position. You could even go really fancy, and calculate the correct x,y position based on the changed z position, so that the item appears where it is supposed to be.
将您想要的项目略微放在您想要位于前面的项目后面。也就是说,实际上改变z值(假设z垂直于屏幕平面)。您不必为了让物品在彼此面前绘制而进行大量更改。如果你只是略微改变z值,你不应该注意到它们所需位置的偏移。你甚至可以非常喜欢,并根据改变的z位置计算正确的x,y位置,以便项目出现在它应该的位置。
#5
1
Your stuff will be drawn in the exact order you call the glBegin/glEnd functions in. You can get depth-buffering using the z-buffer, and if your 2d objects have different z values, you can get the effect you want that way. The only way you are seeing the behavior you describe on the Mac is if the program is drawing stuff in back-to-front order manually or using the z-buffer to accomplish this. OpenGL otherwise does not have any functionality automatically as you describe.
你的东西将按照你调用glBegin / glEnd函数的确切顺序绘制。你可以使用z-buffer获得深度缓冲,如果你的2d对象有不同的z值,你可以获得你想要的效果。您在Mac上看到的行为的唯一方法是,程序是手动以后向前的顺序绘制内容还是使用z-buffer来完成此操作。 OpenGL否则没有您描述的任何功能。
#6
0
As AlanKley pointed out, the way to do this is to disable the depth buffer. The painter's algorithm is really a 2D scan-conversion technique used to render polygons in the correct order when you don't have something like a z-buffer. But you wouldn't apply it to 3D polygons. You'd typically transform and project them (handling intersections with other polygons) and then sort the resulting list of 2D projected polygons by their projected z-coordinate, then draw them in reverse z-order.
正如AlanKley所指出的,这样做的方法是禁用深度缓冲区。画家的算法实际上是一种2D扫描转换技术,用于在没有像z缓冲区这样的东西时以正确的顺序渲染多边形。但是你不会将它应用于3D多边形。您通常会对它们进行变换和投影(处理与其他多边形的交点),然后按照投影的z坐标对生成的2D投影多边形列表进行排序,然后以反向z顺序绘制它们。
I've always thought of the painter's algorithm as an alternate technique for hidden surface removal when you can't (or don't want to) use a z-buffer.
当你不能(或者不想)使用z缓冲区时,我一直认为画家的算法是隐藏表面去除的替代技术。
#1
22
The following call will turn off depth testing causing objects to be drawn in the order created. This will in effect cause objects to draw back to front.
以下调用将关闭深度测试,导致按创建的顺序绘制对象。这实际上会导致对象退回到前面。
glDepthFunc(GL_NEVER); // Ignore depth values (Z) to cause drawing bottom to top
Be sure you do not call this:
请务必不要这样称呼:
glEnable (GL_DEPTH_TEST); // Enables Depth Testing
#2
5
For your specific question, no there is no standardized way to specify depth ordering in OpenGL. Some implementations may do front to back depth ordering by default because it's usually faster, but that is not guaranteed (as you discovered).
对于您的具体问题,没有标准的方法来指定OpenGL中的深度排序。默认情况下,某些实现可能会进行前后深度排序,因为它通常更快,但不能保证(如您所发现的那样)。
But I don't really see how it will help you in your scenario. If you draw a black square in front of a white square the black square should be drawn in front of the white square regardless of what order they're drawn in, as long as you have depth buffering enabled. If they're actually coplanar, then neither one is really in front of the other and any depth sorting algorithm would be unpredictable.
但我真的没有看到它会如何帮助你在你的场景中。如果你在白色正方形前面画一个黑色正方形,那么只要你启用了深度缓冲,就应该在白色正方形前面绘制黑色正方形,而不管它们绘制的顺序是什么。如果它们实际上是共面的,那么任何一个都不是真的在另一个之前,并且任何深度排序算法都是不可预测的。
The tutorial that you posted a link to only talked about it because depth sorting IS relevant when you're using transparency. But it doesn't sound to me like that's what you're after.
您发布链接的教程仅讨论了它,因为深度排序与您使用透明度时相关。但这听起来不像是你所追求的。
But if you really have to do it that way, then you have to do it yourself. First send your white square to the rendering pipeline, force the render, and then send your black square. If you do it that way, and disable depth buffering, then the squares can be coplanar and you will still be guaranteed that the black square is drawn over the white square.
但如果你真的必须这样做,那么你必须自己做。首先将白色方块发送到渲染管道,强制渲染,然后发送黑色方块。如果你这样做,并禁用深度缓冲,那么正方形可以是共面的,你仍然可以保证黑色正方形被绘制在白色正方形上。
#3
2
Drawing order is hard. There is no easy solution. The painter's alogorithm (sort objects by their distance in relation to your camera's view) is the most straightforward, but as you have discovered, it doesn't solve all cases.
绘图顺序很难。没有简单的解决方案。画家的算法(根据他们与相机视图的距离对物体进行排序)是最直接的,但正如您所发现的,它并不能解决所有情况。
I would suggest a combination of the painter's algroithm and layers. You build layers for specific elements on your program. So you got a background layer, objects layers, special effect layers, and GUI layer.
我会建议画家的alrefithm和层的组合。您为程序中的特定元素构建图层。因此,您有一个背景图层,对象图层,特殊效果图层和GUI图层。
Use the painter's algorithm on each layer's items. In some special layers (like your GUI layer), don't sort with the painter's algorithm, but by your call order. You call that white square first so it gets drawn first.
在每个图层的项目上使用画家的算法。在某些特殊图层(如GUI图层)中,不要使用画家的算法排序,而是按照您的调用顺序排序。你首先调用那个白色方块,然后先画出它。
#4
2
Draw items that you want to be in back slightly behind the items that you want to be in the front. That is, actually change the z value (assuming z is perpendicular to the screen plane). You don't have to change it a lot to get the items to draw in front of eachother. And if you only change the z value slightly, you shouldn't notice much of an offset from their desired position. You could even go really fancy, and calculate the correct x,y position based on the changed z position, so that the item appears where it is supposed to be.
将您想要的项目略微放在您想要位于前面的项目后面。也就是说,实际上改变z值(假设z垂直于屏幕平面)。您不必为了让物品在彼此面前绘制而进行大量更改。如果你只是略微改变z值,你不应该注意到它们所需位置的偏移。你甚至可以非常喜欢,并根据改变的z位置计算正确的x,y位置,以便项目出现在它应该的位置。
#5
1
Your stuff will be drawn in the exact order you call the glBegin/glEnd functions in. You can get depth-buffering using the z-buffer, and if your 2d objects have different z values, you can get the effect you want that way. The only way you are seeing the behavior you describe on the Mac is if the program is drawing stuff in back-to-front order manually or using the z-buffer to accomplish this. OpenGL otherwise does not have any functionality automatically as you describe.
你的东西将按照你调用glBegin / glEnd函数的确切顺序绘制。你可以使用z-buffer获得深度缓冲,如果你的2d对象有不同的z值,你可以获得你想要的效果。您在Mac上看到的行为的唯一方法是,程序是手动以后向前的顺序绘制内容还是使用z-buffer来完成此操作。 OpenGL否则没有您描述的任何功能。
#6
0
As AlanKley pointed out, the way to do this is to disable the depth buffer. The painter's algorithm is really a 2D scan-conversion technique used to render polygons in the correct order when you don't have something like a z-buffer. But you wouldn't apply it to 3D polygons. You'd typically transform and project them (handling intersections with other polygons) and then sort the resulting list of 2D projected polygons by their projected z-coordinate, then draw them in reverse z-order.
正如AlanKley所指出的,这样做的方法是禁用深度缓冲区。画家的算法实际上是一种2D扫描转换技术,用于在没有像z缓冲区这样的东西时以正确的顺序渲染多边形。但是你不会将它应用于3D多边形。您通常会对它们进行变换和投影(处理与其他多边形的交点),然后按照投影的z坐标对生成的2D投影多边形列表进行排序,然后以反向z顺序绘制它们。
I've always thought of the painter's algorithm as an alternate technique for hidden surface removal when you can't (or don't want to) use a z-buffer.
当你不能(或者不想)使用z缓冲区时,我一直认为画家的算法是隐藏表面去除的替代技术。