更新使用的顶点缓冲区对象时,应该如何更新顶点数组对象? [英] How should I update a Vertex Array Object when I update a Vertex Buffer Object it uses?

查看:87
本文介绍了更新使用的顶点缓冲区对象时,应该如何更新顶点数组对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过glBufferData()更新VBO(尤其是其大小)可能会更改其物理内存地址,尽管不是glGenBuffers()设置的缓冲区对象名称. VBO通过调用glVertexAttribPointer()链接到VAO,其中有关VBO的信息(缓冲区对象名称?内存地址?)存储在VAO中. 当通过glBindVertexArray()绑定VAO时,该VAO可用于更新和绘制. GL当时会重新计算VBO地址吗? 当链接到的VBO通过glBufferData()更新时,VAO可能会绑定,也可能不会绑定.

Updating a VBO (especially its size) via glBufferData() can potentially change it's physical memory address, though not its buffer object name as set by glGenBuffers(). A VBO is linked to a VAO via a call to glVertexAttribPointer(), where information about the VBO (buffer object name? Memory address?) is stored in the VAO. The VAO becomes available for update and drawing when it is bound via glBindVertexArray(). Does GL recompute the VBO address at that time? The VAO may or may not be bound when a VBO it links to gets updated via glBufferData().

根据何时将缓冲区对象名称转换为物理内存地址,我可以想象到仅通过在更改VBO之后再次绑定VAO即可为更改后的VBO更新VAO.或者,可能有必要通过再次调用glVertexAttribPointer()来更彻底地更新VAO.

Depending on when the buffer object name is translated to a physical memory address, I can imagine that the VAO could be updated for the changed VBO merely by binding the VAO again after changing the VBO; or, it may be necessary to more thoroughly update the VAO with another call to glVertexAttribPointer().

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

So part of this question is: what information about the VBO is stored in the VAO? If it is just the buffer object name, then it shouldn't be necessary to call glVertexAttribPointer() again after changing the VBO contents.

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

Perhaps such details are not part of the API specification, and so the only safe practice is to update a VAO via glVertexAttribPointer() after every update of a linked VBO.

推荐答案

您不必担心,因为VBO从未向您公开底层服务器的内存空间.顶点属性指针相对于设置时绑定到GL_ARRAY_BUFFER的对象的开头.

You do not have to worry about that because VBOs never expose the underlying server memory space to you. Vertex attribute pointers are relative to the beginning of the object bound to GL_ARRAY_BUFFER at the time you set them.

即使您通过调用glBufferData (...)重新分配缓冲区(这会创建一个 new 数据存储,而不是按照您的问题提示进行更新),您的顶点属性指针也不会无效.这是因为它们实际上是偏移到命名缓冲区的内存中,而不是偏移到任意地址中.需要两个信息(缓冲区名称 偏移量)来建立顶点指针.

Even if you re-allocate the buffer by calling glBufferData (...) (this creates a new data store, rather than updating it as your question suggests), your vertex attribute pointers are not going to be invalidated. This is because they are literally offsets into a named buffer's memory rather than arbitrary addresses; it takes two pieces of information (buffer name and offset) to establish a vertex pointer.

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

从缓冲区对象获取数组 时,顶点属性的 VERTEX_ATTRIB_BINDING指示使用哪个顶点缓冲区绑定.这 属性的VERTEX_ATTRIB_RELATIVE_OFFSET与顶点之和 缓冲区绑定的VERTEX_BINDING_OFFSET用作偏移量(基本 机器单元),该缓冲区的数据存储区中的第一个元素.

When an array is sourced from a buffer object, the vertex attribute's VERTEX_ATTRIB_BINDING indicates which vertex buffer binding is used. The sum of the attribute's VERTEX_ATTRIB_RELATIVE_OFFSET and the vertex buffer binding's VERTEX_BINDING_OFFSET is used as the offset (in basic machine units) of the first element in that buffer's data store.

    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的内容).

This code is from an extension / version of OpenGL (4.3) that is not part of the original discussion, but I thought it worth mentioning since for all intents and purposes this is how vertex attribute pointers worked under the hood anyway. The new API gives you the freedom to specify vertex attribute format independent of the vertex buffer (it does not care what is bound to GL_ARRAY_BUFFER at the time you setup the attribute format).

当命令获取数组内存(例如glDrawArrays (...))时,将间接计算地址.

The address is computed indirectly when a command sources array memory (e.g. glDrawArrays (...)).

这篇关于更新使用的顶点缓冲区对象时,应该如何更新顶点数组对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆