通过 glBufferData() 更新 VBO(尤其是其大小)可能会更改其物理内存地址,但不会更改 glGenBuffers() 设置的缓冲区对象名称。
VBO 通过调用 glVertexAttribPointer() 链接到 VAO,其中有关 VBO 的信息(缓冲区对象名称?内存地址?)存储在 VAO 中。
当通过 glBindVertexArray() 绑定 VAO 时,它就可用于更新和绘制。 GL当时是否重新计算VBO地址?
当 VAO 链接到的 VBO 通过 glBufferData() 更新时,VAO 可能会或可能不会被绑定。
根据缓冲区对象名称何时转换为物理内存地址,我可以想象,只需在更改 VBO 后再次绑定 VAO 即可为更改后的 VBO 更新 VAO;或者,可能需要通过再次调用 glVertexAttribPointer() 来更彻底地更新 VAO。
所以这个问题的一部分是:VAO 中存储了有关 VBO 的哪些信息?如果只是缓冲区对象名称,则在更改 VBO 内容后无需再次调用 glVertexAttribPointer()。
也许这些细节不是 API 规范的一部分,因此唯一安全的做法是在每次更新链接的 VBO 后通过 glVertexAttribPointer() 更新 VAO。
您不必担心这一点,因为 VBO 永远不会向您公开底层服务器内存空间。顶点属性指针相对于绑定到的对象的开头GL_ARRAY_BUFFER
在你设置它们的时候。
即使您通过调用重新分配缓冲区glBufferData (...)
(这会创建一个new数据存储,而不是按照您的问题建议更新它),您的顶点属性指针不会失效。这是因为它们实际上是命名缓冲区内存中的偏移量,而不是任意地址;它需要两条信息(缓冲区名称andoffset) 来建立顶点指针。
UPDATE: (Citing implementation details)
以下内容来自GL_ARB_vertex_attrib_binding https://www.opengl.org/registry/specs/ARB/vertex_attrib_binding.txt:
修改第 2.9.6 节“缓冲区对象中的顶点数组”
当数组被获取时从缓冲区对象中,顶点属性的
VERTEX_ATTRIB_BINDING 指示使用哪个顶点缓冲区绑定。这
属性的 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 (...)
).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)