调整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允许直接复用已存在的缓冲区对象来更新数据。
正确的更新方式
- 当数据容量超过原缓冲区大小:直接绑定缓冲区后调用
glBufferData,传入新的尺寸和数据即可。OpenGL会自动重新分配缓冲区内存并上传新数据。 - 当数据容量未超过原缓冲区大小:使用
glBufferSubData仅更新需要修改的区域,能获得更好的性能。如果提前知道数据最大可能容量,也可以在初始化时用glBufferStorage(OpenGL 4.4及以上支持)预分配足够大的内存,后续持续用glBufferSubData更新。
部分电脑点消失的排查方向
- 字节数计算错误:检查
new_data_size_in_bytes是否准确对应new_data_vertices的实际字节数(比如顶点数量×每个顶点的字节大小),错误的尺寸会导致数据上传不完整。 - 驱动同步问题:部分旧显卡驱动对
glBufferData重复调用的同步处理可能存在差异,可以尝试在更新后调用glFinish(仅用于排查,不推荐频繁使用)确认数据是否完成上传。 - 顶点属性配置错误:如果更新数据后顶点格式有变化,需重新调用
glVertexAttribPointer确保属性指针指向正确的缓冲区偏移和格式。
内容的提问来源于stack exchange,提问作者wayright
相关产品推荐
相关产品推荐

