带有 GL_DYNAMIC_DRAW 的 OpenGL VAO
Posted
技术标签:
【中文标题】带有 GL_DYNAMIC_DRAW 的 OpenGL VAO【英文标题】:OpenGL VAO with GL_DYNAMIC_DRAW 【发布时间】:2021-07-21 07:21:24 【问题描述】:我正在使用 OpenGL,在开发过程中我发现这个 GL_DYNAMIC_DRAW 缓冲区模式表明缓冲区数据可能会更改,我想如果我在绑定到某些 VAO 时调用 glBufferData(...) 是否意味着每次我将再次 bing 这个 VAO 内存中的所有数据都会自动重新上传到 GPU?
代码中的相同想法:
data = [...] # List of arrays (actual data)
buffers = glGenBuffers(4) # Create buffers
vao = glGenVertexArrays(1) # Create VAO
glBindVertexArray(vao) # Bind VAO
for i, (buf, data) in enumerate(zip(buffers, data)):
glBindBuffer(GL_ARRAY_BUFFER, buf)
glBufferData(GL_ARRAY_BUFFER, data.nbytes, data, GL_DYNAMIC_DRAW)
glEnableVertexAttribArray(i)
glVertexAttribPointer(i, 3, GL_FLOAT, GL_FALSE, some_straid, ctypes.c_void_p(0))
glBindVertexArray(0) # unbind every thing ...
...
def on_render():
glClear(...) # clear screen
glUseProgram(...) # enable shader
glBindVertexArray(vao) # will this call upload new data to gpu?
glDrawArrays(GL_TRIANGLES, 0, 3) # draw
glBindVertexArray(0) # unbind VAO
glUseProgram(0) # unbind shader
glutSwapBuffers()
如果没有,更新这些缓冲区的最佳方法是什么(每次调用 glBufferData?)?
【问题讨论】:
“这是否意味着每次我再次 bing 这个 VAO 时,我内存中的所有数据都会自动重新上传到 GPU?” - 不,它没有。glBindVertexArray
只是改变一个全局状态。它改变了当前的 VAO 对象。
@Rabbid76,所以每次我想更新缓冲区我都需要调用 glBufferData?
@SlLoWre:是的。每次要更新缓冲区时,都需要调用glBufferData
(或使用其中一种内存映射方法)。 glBufferData
的使用只是对 OpenGL 实现的一个提示,但不会以任何方式改变功能。
【参考方案1】:
缓冲区使用:
usage 是 GL 实现关于如何访问缓冲区对象的数据存储的提示。这使 GL 实现能够做出更智能的决策,这些决策可能会显着影响缓冲区对象的性能。
It does not, however, constrain the actual usage of the data store.
的使用可以分为两部分:第一,访问频率(修改和使用),第二,访问的性质。访问频率可能是以下之一:
针对您的具体情况
动态 - 数据存储内容将被反复修改并多次使用。
如果您想更新缓冲区,您必须调用glBufferData
或任何其他方法,例如:glBufferSubData
、glMapBuffer
。这必须在绑定缓冲区时完成(不是 VAO,而是缓冲区)
【讨论】:
以上是关于带有 GL_DYNAMIC_DRAW 的 OpenGL VAO的主要内容,如果未能解决你的问题,请参考以下文章
使用带有地图附件的 Facebook Open Graph Story (GeoPoint)