在OpenGL 3+中绘制许多纹理四边形的最快方法

时间:2012-10-02 23:01:03

标签: opengl

由于GL_QUADS已从OpenGL 3.1及更高版本中删除,因此在不使用它的情况下绘制大量四边形的最快方法是什么?我已经尝试了几种不同的方法(下面),并在我的机器上对它们进行了速度排序,但我想知道是否有更好的方法,因为最快的方式仍然看起来浪费和不优雅。我应该提一下,在每种方法中我都使用具有交错顶点和纹理坐标的VBO,因为我认为这是最佳实践(尽管我可能是错的)。另外,我应该说我不能在单独的四边形之间重用任何顶点,因为它们将具有不同的纹理坐标。

  1. 使用原始重启索引GL_TRIANGLE_STRIP的glDrawElements,以便索引数组看起来像{0,1,2,3,PRI,4,5,6,7,PRI,...}。这将获取我的VBO中的前4个顶点,将它们视为三角形条带以形成矩形,然后将接下来的4个顶点视为单独的条带。这里的问题只是索引数组似乎浪费了空间。早期版本的OpenGL中GL_QUADS的优点在于它每4个顶点自动重启基元。不过,这是我能找到的最快的方法。

  2. 几何着色器。我为每个矩形传入1个顶点,然后在着色器中构造4个顶点的相应三角形条带。这似乎是最快和最优雅的,但我已经阅读,现在看到,与传递冗余数据相比,几何着色器效率不高。

  3. 带GL_TRIANGLES的glDrawArrays。我只是独立绘制每个三角形,不重复使用顶点。

  4. 带GL_TRIANGLE_STRIP的glMultiDrawArrays,“第一个”数组的所有倍数为4的数组,以及“count”数组的4个数组的数组。这告诉视频卡从0开始绘制前4个,然后从4开始绘制前4个,依此类推。我认为,这个速度太慢的原因是你不能将这些索引数组放在VBO中。

1 个答案:

答案 0 :(得分:4)

你已经涵盖了所有典型的好方法,但我想建议一些不太常见的,我怀疑可能有更高的性能。基于问题的措辞,我将假设您正在尝试绘制m * n个瓷砖阵列,并且它们都需要不同的纹理坐标。

  • 几何着色器不是添加和删除顶点的正确工具。它能够做到这一点,但它确实适用于实际更改动态渲染的基元数量(例如阴影卷生成)的情况。如果你只是想用不同的纹理坐标绘制一大堆相邻的不同基元,我怀疑绝对最快的方法是使用曲面细分着色器。只需传入一个四边形并让曲面细分程序在程序上计算纹理坐标。
  • 类似且更便携的方法是查找每个四边形的纹理坐标。这是微不足道的:假设您正在绘制50x20四边形,您将拥有一个50x20纹理来存储所有纹理坐标。在顶点程序中点击此纹理(或者在几何程序中更有效),并将结果发送到片​​段程序以进行实际渲染。

请注意,在上述两种情况下,您都可以重复使用顶点。在第一种方法中,中间顶点是即时生成的。在第二个中,顶点的纹理坐标在着色器中被替换为纹理中的缓存值。