【问题标题】:OpenGL VBO updating dataOpenGL VBO 更新数据
【发布时间】:2015-11-22 00:56:39
【问题描述】:

我必须绘制一个包含几千个顶点的缓冲区。我正在使用 vbo 来存储数据。

我知道我将不得不多次更新 VBO - 但一次只更新一小部分。

所以我想知道最好的方法是:

  1. 将 VBO 拆分为更小的 VBO(可容纳 300 个顶点),然后通过 1 个调用更新各个 VBO?
  2. 一个大型 VBO 并使用 很多glBufferSubData() 调用?
  3. 使用glMapBuffer() 和一个大VBO?

【问题讨论】:

    标签: c++ opengl buffer vbo


    【解决方案1】:

    还有另一个选项,有点像选项 3 - 使用一个大 VBO(可能使用 GL_STREAM_DRAW 模式),它会重置每一帧(通过使用 NULL 缓冲区指针和相同大小调用 glBufferData每次)然后马上glMapBuffer-ed。缓冲区在填充时保留映射,然后在绘制之前取消映射。重复。

    glBufferData 的调用告诉OpenGL 不需要旧的缓冲区内容,因此glMapBuffer 不必潜在地等待以确保GPU 由GPU 完成。

    这种方法似乎是vertex_buffer_object 扩展官方认可的方法。请参阅“使用映射缓冲区对象的顶点数组”示例:

    http://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt

    这表明 OpenGL(或驱动程序?)将监视这种行为,并(当发现时)安排事情以便有效地执行。

    【讨论】:

      【解决方案2】:
      1. 听起来不是个好主意:它会强制您在多次调用中绘制它,同时更改每次绘制调用之间的绑定缓冲区。
      2. 如果您的缓冲区很大,也许可以解决问题。
      3. 整个缓冲区肯定会上传到 GPU。这肯定会和一个 glBufferData 一样高效,但您可以异步执行此操作。

      如果您的缓冲区很小,如果认为 glBufferData 或 glMapBuffer 是更好的解决方案。 100000 * sizeof(float) * 3 ~= 1MB。应该没有问题。

      【讨论】:

      • 旁注:我已经知道我必须在多次调用中绘制它 - 无论我是否使用许多 VBO。我也知道我一次只会绘制部分顶点。更改绑定的 VBO 缓冲区是否有很多开销?另外,mapBuffer 比 bufferdata 慢吗?
      • mapBuffer 的优点是您可以在 GL 执行其他操作时将数据复制到缓冲区中。另一方面,缓冲区映射的真正性能实际上取决于实现。如果您可以避免多次更改 VBO,我建议您这样做。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-05
      • 1970-01-01
      • 1970-01-01
      • 2014-10-06
      相关资源
      最近更新 更多