标题说明了一切,但为了清楚起见我会添加一些额外的单词.
在这种情况下,调整大小意味着:
编辑
至于解释一些更多的细节并证明我的问题:
我会将(正手)未知大小的数据存储到VBO,但我只知道一个非常粗略估计的上限(在异常条件下10-100倍甚至更多) ).
当然我知道我存储了多少数据,当我完成它时,所以存储数据会很好,直到我发现我的VBO太小并调整它然后再继续存储.
这就是为什么我不想复制(特别是不在CPU端):
我在GPU上做这一切以获得交互式帧速率.当我不得不复制时,它很慢甚至不可能,因为没有足够的空间.最糟糕的是通过CPU复制数据,从而将所有内容通过总线传递到具有足够大小的新内存区域,然后glBufferData
使用新大小的VBO和新内存区域作为源.那将是性能杀手.
绕开
我通过准确估计所需空间来规避问题.但是我会让这个问题在一个星期内无法回答,看看是否有人对此有另一个暗示,因为我对解决方案不太满意.
我认为没有复制你就不会解决这个问题,因为调整缓冲区的唯一方法就是调用glBufferData
,IMO无法告诉驱动程序保留旧数据.
你大概能做些什么来至少没有将其复制到CPU,然后再返回,创造某种辅助VBO的这些目的,直接从VBO到辅助VBO(使用复制ARB_copy_buffer扩展名),调整VBO和复制它的内容回来了.
但我认为最好的方法是预先分配一个更大的缓冲区,因此调整大小不是必需的,但当然在这种情况下你需要知道你需要多少额外的存储空间.
多年后重新审视这个问题,新版本和扩展版本的情况发生了一些变化.
Christian Rau的回答中提到的扩展是自3.1以来的核心,它允许我们将内容(通过glCopyBufferSubData)从一个VBO 复制到另一个VBO.希望驱动程序在GPU端执行此操作!
使用此函数,我们可以创建一个更大的缓冲区并复制前导数据.这样做的缺点是内存需求加倍,因为我们需要两个缓冲区.
好消息是:使用稀疏缓冲区,即将出现更好的解决方案.
鉴于此扩展,我们可以为数据分配一个具有足够空间的虚拟缓冲区,而无需支付不必要的空间.我们只需要"提交"我们实际想要存储数据的内存区域.这意味着我们可以通过在其末尾提交新页面来"增长"VBO.
坏消息是:截至目前的OpenGL版本(4.5),这仍然是一个扩展而不是核心,因此采用这种方法可能是不可能的.您还应该注意,规范中还有一些尚未解决的细节.例如,当前扩展中不允许映射稀疏缓冲区,但可能会在将来的版本中添加支持.
如果您有任何数据,我会热衷于了解此扩展程序的可用性.