即使更改模型视图矩阵,使用顶点缓冲区对象是不是有意义?

Posted

技术标签:

【中文标题】即使更改模型视图矩阵,使用顶点缓冲区对象是不是有意义?【英文标题】:Does it make sense to use Vertex Buffer Objects even when changing the Model View matrix?即使更改模型视图矩阵,使用顶点缓冲区对象是否有意义? 【发布时间】:2009-12-10 04:39:18 【问题描述】:

我希望在我的 iPhone 应用程序上获得一些额外的性能 (FPS) 提升。我已经在使用交错数据、GL_SHORT 和单个纹理图集。请参阅 this question 了解我已经完成的详细信息。

现在我想看看使用 VBO 来提高性能。根据 Apple 的 OpenGL ES 文档,这是一个很好的步骤。但是,它没有说明 VBO 如何(或是否)受到模型视图矩阵更改的影响。本质上,我将同一个对象多次渲染到场景中,但每次都使用稍微不同的模型视图矩阵。对象之间的主要区别(场景中的位置除外)是纹理映射。它们的纹理坐标都略有不同。

VBO 会在这种情况下提供帮助吗?我应该为每个单独的对象分配一个单独的 VBO 吗?

更新 1

到目前为止,VBO 似乎对我的表现有负面影响。 FPS 回落到 20 年代中期到高 20 年代。我分配了 70 个 VBO:35 个用于数据,35 个用于索引。我可以将数据和一个全局索引数组降低到 35 个。我正在使用 glBufferSubData() 根据需要更新纹理坐标。

另一个想法是分解所有静态数据并为该 VBO 指定 GL_STATIC_DRAW。

【问题讨论】:

您是否对 iPhone 3G 或 iPod touch 进​​行了前后性能评估?我不希望在旧设备上移动到 VBO 时帧速率会发生变化,但在支持硬件 VBO 的 GPU 上,如果 GPU 尚未完成读取,对缓冲区对象的部分更新可能会导致驱动程序中的额外工作或同步.这里的重点是“部分”——如果您完全替换数据(即使用 glBufferData),驱动程序通常可以为您处理双缓冲。 评估是在 iPhone 3G 上完成的。 有趣。我建议比较 Shark 中的两个版本,看看时间差异在哪里。如果数据复制有问题,另一种更新缓冲区对象的方法是通过OES_mapbuffer 扩展将其映射到内存中,并直接在其中生成数据。支持硬件 VBO 的 GPU 上的部分更新同样需要注意,因为您可以映射缓冲区并仅更改其中的一部分,但您可以通过调用 glBufferData 来表示您不关心旧内容映射之前的空指针。 【参考方案1】:

它没有说明 VBO 如何(或是否)受到模型视图矩阵更改的影响

每次进行绘图调用时,都会在 GPU 上进行模型视图转换。更改模型视图不会导致 VBO 发生变异。

对象之间的主要区别(场景中的位置除外)是纹理映射。它们的纹理坐标都略有不同。

听起来你应该调整纹理矩阵,除了模型视图矩阵,有点像这样:

glMatrixMode(GL_TEXTURE);
// glTranslate, glRotate, etc
glMatrixMode(GL_MODELVIEW);
// glTranslate, glRotate, etc

利用 VBO 通常是个好主意,但它们实际上只对第三代 iPhone 有帮助。它们对旧 iPhone 没有多大帮助。

我应该为每个单独的对象分配一个单独的 VBO 吗?

减少应用程序中的 VBO 数量通常更有效。您可以在每次调用glDrawArraysglDrawElements 时提供唯一的偏移量,而不是多次调用glBindBuffer

【讨论】:

以上是关于即使更改模型视图矩阵,使用顶点缓冲区对象是不是有意义?的主要内容,如果未能解决你的问题,请参考以下文章

如何将模型矩阵包含到 VBO?

✠OpenGL-4-图形数据

使用矩阵反转顶点缠绕顺序

为啥是模型视图矩阵?

为啥使用 VBO 和/或 IBO 而不是简单的顶点数据?

如何在 OpenGL ES 2.0 中将视图/模型/投影矩阵传递给我的顶点着色器?