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

Opengl 是否可以就地调整VBO的大小?,opengl,vbo,Opengl,Vbo,标题说明了一切,但为了清楚起见,我将添加一些额外的单词 在这种情况下,调整大小意味着: 在旧vbo的末尾获得更多存储空间 在前端保存旧数据 (希望不是复制,但至少不是在CPU端,这意味着驱动程序应该处理这个问题) 编辑 为了解释更多细节并证明我的问题: 我将(正手)未知大小的数据存储到VBO中,但我只知道一个上限,这是一个非常粗略的估计(在异常情况下为10-100倍甚至更多) 当然,当我处理完数据后,我知道我存储了多少数据,所以最好先存储数据,直到我发现我的VBO太小,然后调整它的大小,然后

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

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

  • 在旧vbo的末尾获得更多存储空间
  • 在前端保存旧数据
  • (希望不是复制,但至少不是在CPU端,这意味着驱动程序应该处理这个问题)
编辑

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

当然,当我处理完数据后,我知道我存储了多少数据,所以最好先存储数据,直到我发现我的VBO太小,然后调整它的大小,然后继续存储

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

规避


我通过精确估计所需的空间来回避这个问题。但是我会让这个问题在一周内没有得到回答,看看是否有人对此有其他的提示,因为我对这个解决方案不是很满意。

我认为如果不进行复制,你将无法回避这个问题,因为调整缓冲区大小的唯一方法是调用
glBufferData
,我无法告诉驱动程序保留旧数据

您至少可以不将其复制到CPU上,然后再复制回来,您可以为这些目的创建某种辅助VBO,并直接从VBO复制到辅助VBO(使用扩展名),调整VBO的大小并将其内容复制回来


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

假设您支持最新的OpenGL标准,VBOs的另一种替代方法可能是将数据存储在纹理中(同样,假设您的卡上有足够的内存)。在新旧纹理之间复制数据将在卡上进行,并且不会影响数据传输


具体如何实现这一点取决于代码的具体操作。但原则上,在绘图调用中使用纹理数据覆盖虚拟顶点数据,或者可能使用实例。这需要大量思考和返工。

几年后重新审视这个问题,随着新版本和ext的出现,情况有所改变延期

GPU侧面复制 Christian Rau的回答中提到的扩展是3.1版以来的核心,它允许我们将内容(通过)从一个VBO复制到另一个VBO。希望驱动程序在GPU端做到这一点

使用这个函数,我们可以创建一个更大的缓冲区并复制前导数据。这有一个缺点,即内存需求翻倍,因为我们需要两个缓冲区

真实尺寸调整 好消息是:一个更好的解决方案即将出现

有了这个扩展,我们可以分配一个虚拟缓冲区,为我们的数据分配足够的空间,而无需支付不必要的空间。我们只需“提交”物理上要存储数据的内存区域。这意味着我们可以通过在VBO末尾提交新页来“增长”VBO

坏消息是:从当前的OpenGL版本(4.5)开始这仍然是一个扩展,尚未成为核心,因此采用它可能是不可能的。您也不应该知道规范中有一些细节尚未解决。例如,当前扩展中不允许映射稀疏缓冲区,但在未来版本中可能会添加支持


如果你有关于这个扩展的任何数据,我很想知道它的可用性。

如果你需要一个动态调整大小的VBO,你可以尝试模拟
std::vector
的行为,并在添加元素时得到恒定时间的保护。我也考虑过这一点,但GPU内存(1GB)它有很重的负载,所以没有太多的空间来容纳额外的副本。我记得根据实现读取了调整大小的命令。驱动程序可以调整大小,但不是必需的。顺便说一句,向~rauc;)问候我忘记了大缓冲区:我必须为我不知道但只能估计的数据分配缓冲区。估计给我的分配大小比需要的大约100倍,但我以前无法确定。因此,在这种情况下,我还必须调整(缩小)大小,以避免浪费太多内存,正如我已经说过的那样,这是很罕见的。您是否试图只使用一个(和巨大的)VBO?@Rookie:我希望VBO尽可能小,但它仍然可以很大(>100mb)。但我想至少并行存储其中的3个,以及一些大约40mb大小的额外数据。我不确定VBO的性能在不同的卡之间如何变化,但在我的卡上,我可以使最大1MB VBO,否则我会损失很多性能。想到100MB的VBO听起来很疯狂。尝试将它们拆分为最大1MB的块,我认为即使有100倍以上的VBO(在您的情况下,只有300个VBO),也不会使渲染速度变慢。这也可以解决你的尺寸调整问题。更不用说:在我的卡中,我不能使其大于4MB或其他大小,之后数据会损坏,并且不会渲染其余部分。@新手:对我来说,那些大型VBO不是问题,它们渲染良好,没有损坏的数据或减速。你的卡有多长时间了?我认为在大型VBO上调用300次GLDrawArray要比调用一次开销大得多,但我没有对此进行测试。。。也许你的卡太快了,以至于你认为没有slo