在openGL中,如何让项目从后到前绘制?

发布于 2024-07-06 05:32:18 字数 749 浏览 9 评论 0原文

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

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

我还发现 Mac 上使用 Cocoa NSOpenGLView 的默认行为似乎从后到前,而在 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();                       

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?) ?

I will also mention that I am not interested in a solution using a wrapper library such as 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:

glViewport (0, 0, wd, ht);
glMatrixMode(GL_PROJECTION);           
glLoadIdentity();                      
glOrtho (0.0f, wd, ht, 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);             
glLoadIdentity();                       

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

记忆之渊 2024-07-13 05:32:18

对于您的具体问题,不存在在 OpenGL 中指定深度排序的标准化方法。 某些实现可能会默认执行从前到后的深度排序,因为它通常更快,但这并不能保证(正如您所发现的)。

但我真的不知道它对你的场景有什么帮助。 如果您在白色方块前面绘制黑色方块,则只要启用了深度缓冲,无论它们绘制的顺序如何,黑色方块都应该绘制在白色方块前面。 如果它们实际上是共面的,那么任何一个都不会真正位于另一个的前面,并且任何深度排序算法都将是不可预测的。

您发布链接的教程仅讨论了它,因为当您使用透明度时深度排序是相关的。 但在我看来,这并不是你所追求的。

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

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).

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.

国粹 2024-07-13 05:32:18

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

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

确保你不要这样称呼:

glEnable (GL_DEPTH_TEST);   // Enables Depth Testing

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
红焚 2024-07-13 05:32:18

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

我建议结合画家的算法和图层。 您可以为程序中的特定元素构建层。 这样你就得到了背景层、对象层、特效层和 GUI 层。

对每一层的项目使用画家算法。 在某些特殊层(例如 GUI 层)中,不要使用画家的算法进行排序,而是按照您的调用顺序进行排序。 你首先调用那个白色方块,所以它首先被绘制。

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.

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.

孤单情人 2024-07-13 05:32:18

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

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

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.

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.

泪痕残 2024-07-13 05:32:18

将要放在后面的项目稍微绘制在要放在前面的项目后面。 也就是说,实际更改 z 值(假设 z 垂直于屏幕平面)。 您不必对其进行太多更改即可将项目绘制在彼此面前。 如果您仅稍微更改 z 值,您应该不会注意到与所需位置的偏移量太大。 您甚至可以非常喜欢,根据更改后的 z 位置计算正确的 x,y 位置,以便该项目出现在它应该在的位置。

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.

写给空气的情书 2024-07-13 05:32:18

您的内容将按照您调用 glBegin/glEnd 函数的确切顺序绘制。您可以使用 z 缓冲区获得深度缓冲,如果您的 2d 对象具有不同的 z 值,您可以通过这种方式获得您想要的效果。 您在 Mac 上看到所描述的行为的唯一方法是程序是否按从后到前的顺序手动绘制内容或使用 z 缓冲区来完成此操作。 否则 OpenGL 不会像您所描述的那样自动具有任何功能。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文