You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调整VBO缓冲区大小时是否需要调用glDeleteBuffers/glGenBuffers?

VBO扩容更新时是否需要重新创建缓冲区?

初始化代码

GLuint vertex_buffer;
glGenBuffers(1, &vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, data_size_in_bytes, data_vertices, GL_STATIC_DRAW);

场景与疑问

data_vertices存储了点数据,后续会添加新点并扩容。此时更新缓冲区时,是否需要调用glDeleteBuffers/glGenBuffers?还是仅绑定缓冲区后更新数据即可?

以下是包含疑问的更新代码:

GLuint vertex_buffer;
glDeleteBuffers(1, &vertex_buffer); // 是否必要?
glGenBuffers(1, &vertex_buffer); // 是否必要?
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, new_data_size_in_bytes, new_data_vertices, GL_STATIC_DRAW);

目前我在每帧更新时未调用glDeleteBuffers/glGenBuffers,但部分电脑上出现了点消失的情况。


解答

是否需要重新创建缓冲区?

完全不需要调用glDeleteBuffers和glGenBuffers。反复销毁、重建VBO是低效操作,且毫无必要——OpenGL允许直接复用已存在的缓冲区对象来更新数据。

正确的更新方式

  1. 当数据容量超过原缓冲区大小:直接绑定缓冲区后调用glBufferData,传入新的尺寸和数据即可。OpenGL会自动重新分配缓冲区内存并上传新数据。
  2. 当数据容量未超过原缓冲区大小:使用glBufferSubData仅更新需要修改的区域,能获得更好的性能。如果提前知道数据最大可能容量,也可以在初始化时用glBufferStorage(OpenGL 4.4及以上支持)预分配足够大的内存,后续持续用glBufferSubData更新。

部分电脑点消失的排查方向

  • 字节数计算错误:检查new_data_size_in_bytes是否准确对应new_data_vertices的实际字节数(比如顶点数量×每个顶点的字节大小),错误的尺寸会导致数据上传不完整。
  • 驱动同步问题:部分旧显卡驱动对glBufferData重复调用的同步处理可能存在差异,可以尝试在更新后调用glFinish(仅用于排查,不推荐频繁使用)确认数据是否完成上传。
  • 顶点属性配置错误:如果更新数据后顶点格式有变化,需重新调用glVertexAttribPointer确保属性指针指向正确的缓冲区偏移和格式。

内容的提问来源于stack exchange,提问作者wayright

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 17:52:47