为什么OpenGL缓冲区解除绑定顺序很重要?[duplicate]

flvtvl50  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(192)

此问题在此处已有答案

What is the role of glBindVertexArrays vs glBindBuffer and what is their relationship?(5个答案)
去年关闭了。
我正在用C++学习OpenGL(3.3),我可以使用顶点缓冲对象、顶点数组对象和索引缓冲绘制简单的多边形,但我编写它们的方式仍然感觉有点像魔术,所以我想了解幕后发生了什么。
我对OpenGL使用的绑定系统有一个基本的了解。我还知道 VAO 本身包含绑定索引缓冲区(如这里所指定的),如果我没有弄错的话,也包含绑定顶点缓冲区。
按照这种逻辑,我首先绑定 VAO ,然后创建我的VBO(在 VAO “内部”绑定了哪个?),我可以在VBO上执行操作,并且一切正常。但是,当我在完成设置后解除绑定我使用的缓冲区时,似乎必须首先解除绑定VAO,然后是顶点和索引缓冲区,因此解除绑定的顺序与绑定的顺序相同。而不是以相反的顺序。
这是非常违反直觉的。所以我的问题是,为什么解除约束的顺序很重要?
(to我需要澄清的是,在调用glDrawElements之前,我会重新绑定 VAO ,所以我认为我根本不需要解除绑定任何东西。这主要是为了学习)
下面是相关代码:

GLuint VAO, VBO, IBO;

glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

glBindVertexArray(0); //unbinding VAO here is fine
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//if I unbind VAO here instead, it won't render the shape anymore

while (!glfwWindowShouldClose(window)) {
    glfwPollEvents();

    glUseProgram(shaderProgram);
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, 0);

    glfwSwapBuffers(window);
}
az31mfrm

az31mfrm1#

我想我可能已经想明白了。看着这份解除约束的命令

glBindBuffer(GL_ARRAY_BUFFER, 0); //unbinding VBO
glBindVertexArray(0); //unbinding VAO

显然“破坏”了我的多边形,因为当我的 VAO 仍然绑定时解除绑定VBO意味着VBO,它应该“包含”对它所使用的缓冲区的引用,现在不再绑定到顶点缓冲区。它不知道缓冲区。
首先解除绑定 VAO 允许我在不影响它的情况下解除绑定任何缓冲区。这是正确的顺序。

glBindVertexArray(0); //unbinding VAO
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbinding VBO

OpenGL的绑定系统有点难掌握,尤其是当不同的东西相互依赖时,但我认为我的解释是正确的。希望这能在未来帮助其他学习者。

相关问题