OpenGL - 使用glDrawElements绘制索引

时间:2014-04-20 21:19:31

标签: c++ opengl vertex-array

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

  1. 让我说我将OpenGL指向我的顶点数组。然后我可以使用索引数组调用glDrawElements。它会使用顶点数组中的那些索引正确绘制所需的形状吗?

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

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

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

  5. 如果我只是在幻想我的第四个问题,那么在每一帧中只画出一些多边形会改变多少多边形的快速方法是什么?我是否总是需要传递一组全新的顶点数据才能进行微小的更改?当顶点数据没有改变时,它是否已经这样做了,因为我注意到我无法真正绕过顶点指针调用每一帧。

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

3 个答案:

答案 0 :(得分:2)

  

1.我可以说我将OpenGL传递给我的顶点数组。然后我可以使用索引数组调用glDrawElements。它将绘制   请求使用顶点数组中的索引正确的形状?

  

2.在那个glDrawElements调用后,我可以再做一个glDawElements   用另一组索引调用?它会不会绘制新的索引   使用原始顶点数组的数组?

  

3.当我重做时,OpenGL会保留我的顶点数据到下一帧   所有这些电话?所以下一个顶点指针调用会很多   更快?

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

但是,客户端VA并不是在GL中拥有VA的唯一方式 - 实际上,它们已经完全过时,自GL3.0以来已弃用,并且已从现代版本的OpenGL中删除。现实的做法是使用顶点缓冲区对象,它基本上是由GL 管理但由用户操纵的缓冲区。缓冲区对象只是一块内存,但您需要特殊的GL调用来创建它们,读取或写入或更改数据等等。并且缓冲区对象可能不会存储在系统内存中,而是直接存储在VRAM中,这对于反复使用的静态数据非常有用。看一下the GL_ARB_vertex_buffer_object extension spec,它在2003年开始引入该功能,并成为GL 1.5的核心。

  

4.假设最后三个问题的答案是肯定的,如果我想要怎么办   每帧在多个顶点数组上执行此操作?我假设在做   这对任何超过1个顶点数组都会导致OpenGL掉线   最后一次使用来自图形内存的数组并开始使用新的数组。但   在我的例子中,顶点数组永远不会改变。所以我想要的   知道是否opengl下次保留我的顶点数组以防万一   我发送顶点数据它会是相同的数据吗?如果不是,那就有办法   我可以优化它以允许这样的东西?基本上我想   使用指标在顶点之间以程序方式绘制而不更新   顶点数据,以减少开销和加速复杂   渲染需要不断变化的程序形状   将始终使用原始顶点数组中的顶点。这是   可能还是我只是幻想?

VBOs 正是您所寻找的。

  

5.如果我只是幻想我的第四个问题什么是好事   快速绘制每个帧的大量多边形的方法只有一个   很少会改变?我是否总是要传递一套全新的   顶点数据即使是微小的变化?无论如何它已经这样做了   当顶点数据没有改变,因为我注意到我不能真正得到   在顶点指针周围调用每一帧。

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

答案 1 :(得分:1)

  1. 否。一旦创建了顶点缓冲区对象(VBO),它就会保留在GPU内存中。否则,需要重新传输矢量数据(避免这种情况的旧方法是显示列表)。在这两种情况下,后续帧的性能应保持相似(但使用VBO方法要好得多):您可以在渲染第一帧之前进行VBO创建和下载。
  2. 引入VBO是为了向您提供此功能。只需创建几个VBO。当你需要比现有更多的GPU内存时,事情会变得混乱。
  3. VBO仍然是答案,请参阅Modifying only a specific element type of VBO buffer data?

答案 2 :(得分:0)

听起来你应该尝试一种名为Vertex Buffer Objects的东西。它提供与顶点数组相同的优点,但您可以创建多个顶点缓冲区并将它们存储在"命名的插槽"中。由于数据直接存储在图形卡存储器中,因此该方法具有更好的性能。

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

相关问题