更新它使用的顶点缓冲区对象时,如何更新顶点数组对象?

时间:2015-01-12 22:11:20

标签: opengl

通过glBufferData()更新VBO(特别是它的大小)可能会改变它的物理内存地址,但不是glGenBuffers()设置的缓冲区对象名。 VBO通过调用glVertexAttribPointer()链接到VAO,其中有关VBO(缓冲区对象名称?存储器地址?)的信息存储在VAO中。 当通过glBindVertexArray()绑定时,VAO可用于更新和绘图。 GL当时是否重新计算VBO地址? 当链接到的VBO通过glBufferData()更新时,VAO可能绑定也可能不绑定。

根据缓冲区对象名称何时转换为物理内存地址,我可以想象只需在更改VBO后再次绑定VAO就可以为更改的VBO更新VAO;或者,可能需要通过再次调用glVertexAttribPointer()来更彻底地更新VAO。

这个问题的一部分是:关于VBO的哪些信息存储在VAO中?如果它只是缓冲区对象名称,则在更改VBO内容后不必再次调用glVertexAttribPointer()。

也许这些细节不是API规范的一部分,因此唯一安全的做法是在每次更新链接的VBO后通过glVertexAttribPointer()更新VAO。

1 个答案:

答案 0 :(得分:7)

您不必担心这一点,因为VBO永远不会向您公开底层服务器内存空间。顶点属性指针相对于设置它们时绑定到GL_ARRAY_BUFFER的对象的开头。

即使你通过调用glBufferData (...)重新分配缓冲区(这会创建一个 new 数据存储,而不是像你的问题建议那样更新它),你的顶点属性指针也不会失效。这是因为它们实际上偏移到命名缓冲区的内存而不是任意地址;它需要两条信息(缓冲区名称 偏移量)来建立顶点指针。


更新: (引用实施细节)

以下内容来自GL_ARB_vertex_attrib_binding

  

修改第2.9.6节,"缓冲区对象中的顶点数组"

     
    

从缓冲区对象中获取数组 时,顶点属性为< em>         VERTEX_ATTRIB_BINDING指示使用哪个顶点缓冲区绑定。该         属性&rs; VERTEX_ATTRIB_RELATIVE_OFFSET和顶点的总和         缓冲区绑定的VERTEX_BINDING_OFFSET用作偏移量(基本的         机器单元)缓冲区数据存储中的第一个元素。

  
    bindingIndex = VERTEX_ATTRIB_BINDING[attribIndex];
    buffer = VERTEX_BINDING_BUFFER[bindingIndex];

    if (buffer->name != 0) {
        address = buffer->baseAddress + 
                  VERTEX_BINDING_OFFSET[bindingIndex] + 
                  VERTEX_ATTRIB_RELATIVE_OFFSET[attribIndex];
    }

此代码来自OpenGL(4.3)的扩展/版本,它不是原始讨论的一部分,但我认为值得一提,因为无论如何,这都是顶点属性指针在引擎盖下工作的方式。新的API使您可以自由地指定独立于顶点缓冲区的顶点属性格式(它不关心在设置属性格式时绑定到GL_ARRAY_BUFFER的内容)。

当命令源数组内存(例如glDrawArrays (...))时间接计算地址。