8

我正在制作一个小型 2D 游戏演示,根据我所阅读的内容,使用drawElements()绘制索引三角形列表比drawArrays()绘制未索引三角形列表更好。

但据我所知,似乎不可能在单个绘图调用中绘制多个未连接的元素drawElements()

因此,对于我只会绘制由两个三角形组成的正方形的 2D 游戏演示,最好的方法是什么,这样我就不会结束每个对象有一个绘制调用?

4

1 回答 1

7

是的,在许多情况下最好使用索引,因为您不必存储或传输重复的顶点,也不必处理重复的顶点(顶点着色器只需要每个顶点运行一次)。在四边形的情况下,您将 6 个顶点减少到 4 个,外加少量索引数据。三分之二确实是一个很好的改进,特别是如果您的顶点数据不仅仅是位置。

总之,glDrawElements结果

  • 更少的数据(大部分),这意味着更多的 GPU 内存用于其他事情
  • 如果数据发生变化,更新速度更快
  • 更快地传输到 GPU
  • 更快的顶点处理(无重复)

如果内存中的引用顶点彼此不靠近,则索引会影响缓存性能。建模者通常会生成考虑到这一点而优化的网格。

对于多个元素,如果您指的是GL_TRIANGLE_STRIP可以使用一次调用glPrimitiveRestartIndex绘制多条三角形。在您的情况下,使用和引用每个四边形有 6 个索引的 4 个顶点glDrawElements很容易。GL_TRIANGLES然后,您的顶点数组需要存储所有四边形的所有顶点。如果他们正在移动,您仍然需要每帧将数据发送到 GPU。您可以将所有移动的四边形放置在阵列的前面,并且只更新活动的四边形。您还可以将静态顶点数据存储在单独的数组中。

绘制 3D 模型的典型方法是提供几何的固定顶点列表,并使用模型矩阵(作为模型视图的一部分)移动整个物体。这里令人困惑的部分是网格数据非常小,正如您所说,绘制调用的开销可能会变得非常突出。我认为您必须先画很多四边形,然后才能到达问题所在的阶段。但是,如果你这样做了,实例化或一些类似的想法(如粒子系统)是你应该关注的地方。

如果绘图调用或数据传输成为问题,也许只有沿着以下轨道走,因为涉及很多。完全在 GPU 上实现粒子系统的一个好方法是在纹理中存储实例属性,例如位置/颜色。您使用 FBO/render-to-texture 的每一帧在另一个纹理之间“乒乓”这些数据并更新片段着色器中的属性。要绘制粒子,您可以设置一个静态 VBO,该 VBO 存储具有属性数据纹理坐标的四边形,以便在可以读取和应用粒子位置的顶点着色器中使用。我确信那里有很多好的教程/实现可以遵循(如果你知道一个好的,请发表评论)

于 2013-10-28T14:32:42.917 回答