为何两次调用glBindBuffer()?OpenGL代码疑问求助
为什么OpenGL代码中要两次调用
glBindBuffer(GL_ARRAY_BUFFER, VBO_axes)? 首先看你提供的代码:
void prepare_axes(void) { axes[0][0] = -win_width / 2.5f; axes[0][1] = 0.0f; axes[1][0] = win_width / 2.5f; axes[1][1] = 0.0f; axes[2][0] = 0.0f; axes[2][1] = -win_height / 2.5f; axes[3][0] = 0.0f; axes[3][1] = win_height / 2.5f; // Initialize vertex buffer object. glGenBuffers(1, &VBO_axes); glBindBuffer(GL_ARRAY_BUFFER, VBO_axes); glBufferData(GL_ARRAY_BUFFER, sizeof(axes), axes, GL_STATIC_DRAW); // Initialize vertex array object. glGenVertexArrays(1, &VAO_axes); glBindVertexArray(VAO_axes); glBindBuffer(GL_ARRAY_BUFFER, VBO_axes); glVertexAttribPointer(LOC_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); }
你的疑问:
我在研究上述OpenGL代码时,无法理解为何要两次调用
glBindBuffer(GL_ARRAY_BUFFER, VBO_axes)。根据我的理解,第一次调用glGenBuffers、glBindBuffer和glBufferData后,变量axes的数据已存储到GL_ARRAY_BUFFER中。之后生成并绑定VAO时再次调用该函数,我对此感到困惑。我知道glBufferData()会删除当前缓冲存储(如果存在)并创建新的存储,这意味着第二次调用glBindBuffer时axes的数据会丢失,恳请解答。
先纠正你一个关键误解:第二次调用glBindBuffer根本不会导致数据丢失。glBindBuffer只是把指定的VBO绑定到GL_ARRAY_BUFFER这个目标上,它不会修改缓冲内部的任何数据——只有glBufferData、glBufferSubData这类函数才会操作缓冲的存储内容。
咱们分别拆解这两次绑定的作用:
第一次绑定:给VBO写入数据
glGenBuffers生成一个新的VBO ID,glBindBuffer(GL_ARRAY_BUFFER, VBO_axes)把这个VBO绑定到当前的GL_ARRAY_BUFFER目标。- 随后的
glBufferData会把axes数组里的顶点数据写入到当前绑定在GL_ARRAY_BUFFER上的VBO(也就是VBO_axes)。完成这一步后,数据就永久存在这个VBO里了——哪怕你解绑GL_ARRAY_BUFFER,数据也不会消失。
第二次绑定:让VAO记住顶点属性与VBO的关联
- 当你调用
glBindVertexArray(VAO_axes)后,当前的VAO会成为“活动”状态,后续所有的顶点属性配置(比如glVertexAttribPointer)都会被这个VAO记录下来。 glVertexAttribPointer的核心作用之一,是告诉OpenGL:“当前要配置的顶点属性(这里是LOC_VERTEX),它的数据来源于当前绑定在GL_ARRAY_BUFFER上的缓冲”。而且这个关联关系会被VAO保存——之后只要绑定这个VAO,OpenGL就知道该从哪个VBO取对应顶点属性的数据。- 所以这时候必须再次绑定
VBO_axes到GL_ARRAY_BUFFER,这样glVertexAttribPointer才能正确建立顶点属性和VBO的关联。如果跳过这一步,glVertexAttribPointer会把顶点属性关联到当前绑定的其他缓冲(甚至是默认的0缓冲),后续绘制时必然出错。
额外补充
其实第一次绑定完成数据写入后,你完全可以立刻调用glBindBuffer(GL_ARRAY_BUFFER, 0)解绑,因为数据已经安全存在VBO里了——直到配置VAO的时候,才需要再次绑定来建立关联。
总结来说:两次绑定的目的完全不同,第一次是为了往VBO里存数据,第二次是为了让VAO记住顶点属性对应的VBO,两者互不冲突,也绝不会导致数据丢失。
内容的提问来源于stack exchange,提问作者alryosha
相关产品推荐
相关产品推荐

