0

我有几个关于 OpenGL 如何处理这些绘图操作的问题。

  1. 因此,假设我将 OpenGL 指针传递给我的顶点数组。然后我可以用一组索引调用 glDrawElements。它将使用顶点数组中的那些索引绘制请求的形状对吗?

  2. 在 glDrawElements 调用之后,我可以用另一组索引进行另一个 glDawElements 调用吗?然后它会使用原始顶点数组绘制新的索引数组吗?

  3. 当我重做所有这些调用时,OpenGL 是否会为下一帧保留我的顶点数据?那么下一个顶点指针调用会快很多吗?

  4. 假设最后三个问题的答案是肯定的,如果我想在每帧的多个顶点数组上执行此操作怎么办?我假设在超过 1 个顶点数组上执行此操作会导致 OpenGL 从图形内存中删除最后使用的数组并开始使用新的数组。但就我而言,顶点数组永远不会改变。所以我想知道的是opengl是否会保留我的顶点数组,以防下次我发送顶点数据时它会是相同的数据?如果没有,有没有办法可以优化它以允许这样的事情?基本上,我想在不更新顶点数据的情况下使用索引在顶点之间进行程序绘制,以减少开销并加速复杂的渲染,这需要不断变化的形状,这些形状将始终使用原始顶点数组中的顶点。

  5. 如果我只是幻想我的第四个问题,有什么好的快速方法可以在每帧中绘制大量多边形而只有少数会改变?即使是很小的变化,我是否总是需要传入一组全新的顶点数据?当顶点数据没有改变时,它是否已经这样做了,因为我注意到我无法真正绕过顶点指针调用每一帧。

  6. 随意完全抨击我在断言中犯的任何逻辑错误。我正在努力学习有关opengl如何工作的一切,并且我目前对它如何工作的假设完全有可能是错误的。

4

3 回答 3

3

1.假设我将OpenGL指针传递给我的顶点数组。然后我可以用一组索引调用 glDrawElements。它将使用顶点数组中的那些索引绘制请求的形状对吗?

是的。

2.在那次 glDrawElements 调用之后,我可以用另一组索引进行另一个 glDawElements 调用吗?然后它会使用原始顶点数组绘制新的索引数组吗?

是的。

3.当我重做所有这些调用时,OpenGL 是否会为下一帧保留我的顶点数据?那么下一个顶点指针调用会快很多吗?

回答这个问题比你可能更棘手。你问这些问题的方式让我假设你使用客户端顶点数组,也就是说,你的系统内存中有一些数组,让你的顶点指针直接指向那些。在这种情况下,答案是no。GL 不能以任何有用的方式“缓存”该数据。绘制调用完成后,它必须假设您可能会更改数据,并且必须比较每一位以确保您没有更改任何内容。

然而,客户端 VA 并不是在 GL 中拥有 VA 的唯一方式——实际上,它们已经完全过时,自 GL3.0 以来已被弃用,并且已从现代版本的 OpenGL 中删除。现代的瘦身方法是使用Vertex Buffer Objects,它基本上是由 GL 管理但由用户操作的缓冲区。缓冲区对象只是一块内存,但您将需要特殊的 GL 调用来创建它们、读取或写入或更改数据等。并且缓冲区对象很可能不会存储在系统内存中,而是直接存储在 VRAM 中,这对于反复使用的静态数据非常有用。看看GL_ARB_vertex_buffer_object 扩展规范,最初在 2003 年引入了该功能,并成为 GL 1.5 的核心。

4.假设最后三个问题的答案是肯定的,如果我想每帧在多个顶点数组上做这个怎么办?我假设在超过 1 个顶点数组上执行此操作会导致 OpenGL 从图形内存中删除最后使用的数组并开始使用新的数组。但就我而言,顶点数组永远不会改变。所以我想知道的是opengl是否会保留我的顶点数组,以防下次我发送顶点数据时它会是相同的数据?如果没有,有没有办法可以优化它以允许这样的事情?基本上,我想在不更新顶点数据的情况下使用索引在顶点之间进行程序绘制,以减少开销并加速复杂的渲染,这需要不断变化的形状,这些形状将始终使用原始顶点数组中的顶点。

VBO正是您正在寻找的,在这里。

5.如果我只是幻想我的第四个问题,有什么好的快速方法可以在每帧中绘制大量多边形而只有少数会改变?即使是很小的变化,我是否总是需要传入一组全新的顶点数据?当顶点数据没有改变时,它是否已经这样做了,因为我注意到我无法真正绕过顶点指针调用每一帧。

您也可以只更新 VBO 的一部分。但是,如果您有许多随机分布在缓冲区中的小部分,它可能会变得低效,更新连续(子)区域会更有效。但这本身就是一个话题。

于 2014-04-20T21:36:35.520 回答
1
  1. 是的
  2. 是的
  3. 不会。一旦您创建了顶点缓冲区对象 (VBO),它将保留在 GPU 内存中。否则需要重新传输矢量数据(避免这种情况的旧方法是显示列表)。在这两种情况下,后续帧的性能应该保持相似(但使用 VBO 方法要好得多):您可以在渲染第一帧之前创建和下载 VBO。
  4. 引入 VBO 就是为了准确地为您提供此功能。只需创建几个 VBO。当您需要的 GPU 内存超出可用内存时,事情就会变得一团糟。
  5. VBO 仍然是答案,请参阅Modifying only a specific element type of VBO buffer data?
于 2014-04-20T21:32:38.017 回答
0

听起来您应该尝试一种称为顶点缓冲区对象的东西。它提供与顶点数组相同的好处,但您可以创建多个顶点缓冲区并将它们存储在“命名槽”中。这种方法具有更好的性能,因为数据直接存储在图形卡内存中。

是一个很好的 C++ 教程。

于 2014-04-20T21:37:44.530 回答