VBO 如何连接到 VAO

how does a VBO get attached to a VAO

VAO 是顶点数组对象,VBO 是顶点缓冲区对象。创建和 binding/unbinding VAO 和 VBO 的调用具有如下所示的通用格式:

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

        glGenBuffers(1, &VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
            glBufferData(GL_ARRAY_BUFFER, 
                            sizeof(GLfloat)* 9,
                            vertices,
                            GL_STATIC_DRAW);
            glVertexAttribPointer(0,
                    3, GL_FLOAT, GL_FALSE,
                    0, 0);
            glEnableVertexAttribArray(0);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);    

我在网上看了一些教程,他们说 VBO 绑定到 VAO,但是在上面的代码中,我不明白 "connection" 或 "binding" 在VBO和VAO之间建立?我的意思是我们怎么知道哪个 VBO 绑定到哪个 VAO,如果一个 VBO 要绑定到多个 VAO 怎么办?

所以,基本问题是:VBO 绑定到 VAO 是什么意思,我们怎么知道哪个 VBO 绑定到哪个 VAO,这个绑定是如何建立的?

how does a VBO get attached to a VAO

调用glVertexAttribPointer时附加

Vertex Array Objects state vector may refer to a different Vertex Buffer Object. This reference is stored when glVertexAttribPointer 中规定的每个属性都会被调用。 然后当前绑定到目标 ARRAY_BUFFER 的缓冲区与属性相关联,对象的名称(值)存储在 VAO 的状态向量中。 ARRAY_BUFFER 绑定是一个全局状态。

这与 Index Buffer (ELEMENT_ARRAY_BUFFER) 的行为不同。索引缓冲区绑定在顶点数组对象中说明。当缓冲区绑定到目标 ELEMENT_ARRAY_BUFFER 时,此缓冲区将关联到当前绑定的顶点数组对象。


这意味着当您调用 glBindBuffer(GL_ARRAY_BUFFER, VBO); 时,将设置存储 VBO 的全局状态。 glVertexAttribPointer 从全局状态中检索 VBO 并将其关联到 VAO。 当再次调用glBindBuffer(GL_ARRAY_BUFFER, ...)时,之前的绑定就丢失了,当然不会改变VAO的任何状态。

glBindVertexArray(VAO);              # bind VAO (global state)

glBindBuffer(GL_ARRAY_BUFFER, VBO1); # bind VBO1 (global state)
glVertexAttribPointer(0, ...);       # associate VBO1 to attribute 0 in VAO

glBindBuffer(GL_ARRAY_BUFFER, VBO2); # bind VBO2 (change global state, VBO1 binding is lost)
glVertexAttribPointer(1, ...);       # associate VBO2 to attribute 1 in VAO