VBO 如何连接到 VAO

juz*_*ode 4 opengl vertex-array-object vertex-buffer-objects

VAO 是顶点数组对象,VBO 是顶点缓冲区对象。创建和绑定/解除绑定 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);    
Run Code Online (Sandbox Code Playgroud)

我在互联网上学习了一些教程,他们说 VBO 绑定到 VAO,但是在上面的代码中,我不明白 VBO 和 VAO 之间是如何建立“连接”或“绑定”的? 我的意思是我们怎么知道哪个 VBO 绑定到哪个 VAO 以及如果一个 VBO 绑定到多个 VAO 呢?

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

Rab*_*d76 12

VBO 如何连接到 VAO

它在glVertexAttribPointer被调用时附加。

Vertex Array Objects状态向量中声明的每个属性可以引用不同的Vertex Buffer Object。这个引用在glVertexAttribPointer被调用时被存储。然后将当前绑定到目标的缓冲区ARRAY_BUFFER与属性相关联,并将对象的名称(值)存储在 VAO 的状态向量中。该ARRAY_BUFFER绑定是一个全球性的状态。

这与索引缓冲区( ELEMENT_ARRAY_BUFFER) 的行为不同。索引缓冲区绑定在顶点数组对象中声明。当缓冲区绑定到 target 时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
Run Code Online (Sandbox Code Playgroud)

  • @juztcode 否。当调用 `glVertexAttribPointer` 时,VBO 就会关联到 VAO。当`glBindBuffer(GL_ARRAY_BUFFER, VBO)`被调用时,全局状态被设置。`glVertexAttribPointer` 从全局状态获取 VBO 并将其关联到 VAO。我在答案中添加了一些解释。 (2认同)