是否可以就地调整VBO的大小?

Nob*_*ody 11 opengl vbo

标题说明了一切,但为了清楚起见我会添加一些额外的单词.

在这种情况下,调整大小意味着:

  • 在旧的vbo结束时获得更多的存储空间
  • 将旧数据保存在前面
  • (希望不要复制,但至少不要在CPU端,这意味着驱动程序应该处理这个)

编辑

至于解释一些更多的细节并证明我的问题:
我会将(正手)未知大小的数据存储到VBO,但我只知道一个非常粗略估计的上限(在异常条件下10-100倍甚至更多) ).

当然我知道我存储了多少数据,当我完成它时,所以存储数据会很好,直到我发现我的VBO太小并调整它然后再继续存储.

这就是为什么我不想复制(特别是不在CPU端):
我在GPU上做这一切以获得交互式帧速率.当我不得不复制时,它很慢甚至不可能,因为没有足够的空间.最糟糕的是通过CPU复制数据,从而将所有内容通过总线传递到具有足够大小的新内存区域,然后glBufferData使用新大小的VBO和新内存区域作为源.那将是性能杀手.

绕开

我通过准确估计所需空间来规避问题.但是我会让这个问题在一个星期内无法回答,看看是否有人对此有另一个暗示,因为我对解决方案不太满意.

Chr*_*ica 7

我认为没有复制你就不会解决这个问题,因为调整缓冲区的唯一方法就是调用glBufferData,IMO无法告诉驱动程序保留旧数据.

你大概能做些什么来至少没有将其复制到CPU,然后再返回,创造某种辅助VBO的这些目的,直接从VBO到辅助VBO(使用复制ARB_copy_buffer扩展名),调整VBO和复制它的内容回来了.

但我认为最好的方法是预先分配一个更大的缓冲区,因此调整大小不是必需的,但当然在这种情况下你需要知道你需要多少额外的存储空间.

  • 如果你需要一个动态调整大小的VBO,你可以尝试模拟`std :: vector`的行为,并在添加元素时获得armortized常量时间. (5认同)

Nob*_*ody 7

多年后重新审视这个问题,新版本和扩展版本的情况发生了一些变化.

GPU端复制

Christian Rau的回答中提到的扩展是自3.1以来的核心,它允许我们将内容(通过glCopyBufferSubData)从一个VBO 复制到另一个VBO.希望驱动程序在GPU端执行此操作!

使用此函数,我们可以创建一个更大的缓冲区并复制前导数据.这样做的缺点是内存需求加倍,因为我们需要两个缓冲区.

真正的大小调整

好消息是:使用稀疏缓冲区,即将出现更好的解决方案.

鉴于此扩展,我们可以为数据分配一个具有足够空间的虚拟缓冲区,而无需支付不必要的空间.我们只需要"提交"我们实际想要存储数据的内存区域.这意味着我们可以通过在其末尾提交新页面来"增长"VBO.

坏消息是:截至目前的OpenGL版本(4.5),这仍然是一个扩展而不是核心,因此采用这种方法可能是不可能的.您还应该注意,规范中还有一些尚未解决的细节.例如,当前扩展中不允许映射稀疏缓冲区,但可能会在将来的版本中添加支持.

如果您有任何数据,我会热衷于了解此扩展程序的可用性.