为什么顶点缓冲区对象可以提高性能?


10

根据我的基本了解,顶点缓冲区对象的工作原理如下(伪代码):

通常,如果要说画一个正方形,可以发出画线命令。

line (0, 0) -> (1, 0)
line (1, 0) -> (1, 1)
line (1, 1) -> (0, 1)
line (0, 1) -> (0, 0)

如果我理解正确,则使用VBO会将顶点加载到VBO中。

define VBO
load (0,0) -> VBO
load (1,0) -> VBO
load (1,1) -> VBO
load (0,1) -> VBO
load (0,0) -> VBO

然后,您可以发出一个绘图命令。

draw VBO vertices

虽然我了解VBO的工作原理,但不知道为什么它们会提高性能。

他们如何提高性能?

Answers:


11

通常,在即时模式下渲染对象时(例如,发出线条绘制命令),您会构建一系列提交给图形卡进行绘制的命令。如果要绘制大量数据或绘制频率很高,则可能会浪费大量时间一次又一次地发送此数据。

顶点缓冲区使您可以生成一次提交给图形卡的单个对象。如果不需要更改几何形状,则可以将其保留在图形卡上,只需向图形卡发送绘制该对象的请求即可。由于它在每次绘制时都避免了复制,因此每次绘制的开销要少得多。

请注意,使用顶点缓冲区对象并不总是能够提供非常明显的加速效果。如果每帧只绘制一次对象,并且要替换每帧之间的几何图形,那么避免避免复制每帧都没有好处。

我的大部分经验来自使用诸如OpenGL之类的图形API编写程序,因此,对图形驱动程序的后端感到困惑的人可能可以提供更详细的答案,但是我希望这可以使事情变得更清楚。


10

有两个步骤可使VBO比即时模式更有效率。

  1. 即时模式glBegin / glEndglVertex *等)意味着在每一帧上,您将顶点,每个属性的属性(位置,法线,颜色等)输入驱动程序,驱动程序将其重新格式化并最终发送整个程序包作为对GPU的命令。每帧的每个顶点有很多函数调用。
    (请注意,从OpenGL 3.0开始不推荐使用即时模式,并且从3.2完全删除即时模式。)

  2. 通过使用顶点数组(请参阅glDrawArraysglDrawElementsglVertexPointer等),您可以立即为驱动程序提供全部内容,并节省了重新设置顶点格式的负担。您可以通过整个网格的少量调用有效地替换每个顶点的多个函数调用。但是您仍然需要这样做一次。

  3. 顶点缓冲区对象 VBO(请参阅 glGenBuffers glBindBuffer等)再进一步一步,将数据存储在GPU端:您只发送一次,然后仅通过句柄引用即可。通过不在每个帧上一遍又一遍地发送相同的数据来节省带宽。


6

通过使用即时模式界面(例如,旧式OpenGL glBegin()/ glEnd()/ glVertex()),您可以一次有效地将数据滴加到驱动程序中。然后,它必须获取单个数据,将其重新格式化并传递给硬件(如今,这意味着将其放入命令缓冲区)。

通过使用顶点缓冲区对象,可以在需要使用驱动程序之前向驱动程序提供(希望)大数据块。它可以执行许多优化(重新格式化,放置到视频内存中),而且不必零碎地喂GPU。

在实践中,如果只绘制少量图元,则可能不会有太大区别,但是,如果绘制数百万个三角形网格,则视频内存中的VBO是可行的方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.