我将VBO理解为GPU内存中的缓存非常快并且可以存储顶点数组数据。现在,在每次绘制GPU之前,应该先找出它应该绘制的内容,然后才能使用例如glVertexAttribPointer
设置顶点数组数据。现在它应该将值复制到GPU。每次指定每次应使用的内存时,为了不复制。但是如果在每次更新时我应该改变VBO,即应该再次从CPU复制到GPU。那有什么区别呢?
答案 0 :(得分:2)
从主机内存到VRAM的转移(如果这样的事实实际存在)只是VBO的一个方面。 VBO不必驻留在VRAM中。 GL实现将根据您提供的提示确定位置,并根据观察到的访问模式进行一些二次猜测。对于每帧更新的缓冲区,很可能它永远不会在VRAM中分配,而是在主机内存中的GART区域中分配,它只是映射到GPU地址空间。
您应该知道现代GL实现是多线程的并且操作高度异步。没有维也纳各组织的绘图有一些严重的影由于客户端内存完全不在GL的控制之下,因此必须在绘图功能返回之前处理数据(因为您可以在之后立即修改该内存)。因此它要么必须等到绘制调用完成(隐式同步对整体性能非常糟糕),要么必须使数据的另一个副本能够提前返回并处理稍后画电话。
使用缓冲区对象实际上消除了这样的额外副本。如果您首先使用映射缓冲区,则尤其如此。无论您是从文件加载数据还是动态计算它们,您都可以直接将其存储在映射缓冲区而不是普通客户机内存中。
答案 1 :(得分:1)
使用客户端缓冲区(无VBO),每次进行绘制调用时,都会根据需要将内存从顶点/索引缓冲区复制到GPU。使用VBO,可以通过多种方式从CPU传输内存,每种方式都会影响性能(由于同步)和内存(由于潜在的多缓冲)。
如果您只使用绘图中的整个缓冲区进行一次绘制调用,并使用同步更新(例如glBufferData
)每帧更新整个缓冲区,那么驱动程序可能会执行相同的操作来执行命令,结果将是相同的。虽然,这不能保证。
您应该阅读有关缓冲流的this文章,该文章解释了更新缓冲区的不同方法,没有VBO可用的方法。如果您可以使用它们,这些更新方法可以提供更有效的流式传输。