【问题标题】:how does a VBO get attached to a VAOVBO 如何连接到 VAO
【发布时间】:2020-01-24 07:27:55
【问题描述】:

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);    

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

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

【问题讨论】:

    标签: opengl vertex-array-object vertex-buffer-objects


    【解决方案1】:

    VBO 如何连接到 VAO

    在调用glVertexAttribPointer时附加。

    Vertex Array Objects 状态向量中声明的每个属性可能引用不同的Vertex Buffer Object。此引用在调用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
    

    【讨论】:

    • 据我所知,我的技术文献能力很差:当您调用 glBindBuffer(GL_ARRAY_BUFFER, VBO); 时,绑定到目标的缓冲区即 GL_ARRAY_BUFFER 与当前活动的 VAO 相关联?我得到这个了吗?并且将多个 VBO 与 VAO 相关联是通过将更多 VBO 绑定到同一个目标而不取消绑定 VAO 来完成的?我也正确地得到了这部分吗?
    • @juztcode No. 当glVertexAttribPointer 被调用时,VBO 与 VAO 相关联。当glBindBuffer(GL_ARRAY_BUFFER, VBO) 被调用时,将设置一个全局状态。 glVertexAttribPointer 从全局状态获取 VBO 并将其关联到 VAO。我已经为答案添加了一些解释。
    • @juztcode 不,只说明了最后一个。您必须在glVertexAttribPointer 之前绑定正确的 VBO。 VAO 可以为每个属性存储一个 VBO。
    • 好的,如果我有一行代码包含glBindBuffer(...); glBindBuffer(...); ,那么第一个缓冲区会丢失,因为没有调用glVertexAttribPointer
    • 好的,我终于明白了,谢谢。但是,绑定丢失了,但生成的 VBO 并没有被删除,对吧?我们如何删除它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 2014-09-09
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多