带有 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 或任何其他方法,例如:glBufferSubDataglMapBuffer。这必须在绑定缓冲区时完成(不是 VAO,而是缓冲区)

【讨论】:

以上是关于带有 GL_DYNAMIC_DRAW 的 OpenGL VAO的主要内容,如果未能解决你的问题,请参考以下文章

Facebook Open Graph 发布带有对象的操作

window.open 打开新窗口带有原来地址怎么处理

3.部署场景1:带有遗留的Open vSwitch

使用带有地图附件的 Facebook Open Graph Story (GeoPoint)

带有 java 关键字的机器人框架:Selenium.open(..) 以隐藏模式打开 Firefox 浏览器

带有REST和Open API的gRPC