C++ OpenGL VBO更新数据

C++ OpenGL VBO更新数据,c++,opengl,buffer,vbo,C++,Opengl,Buffer,Vbo,我必须画一个缓冲区来容纳几千个顶点。我正在使用vbo来存储数据 我知道我必须多次更新VBO,但每次只能更新一小部分 因此,我想知道这样做的最佳方法是: 将VBO拆分为更小的VBO(可容纳300个顶点),然后用一个调用更新单个VBO 一个大型VBO并使用大量的glBufferSubData()调用 使用glMapBuffer()和一个大型VBO 听起来不是个好主意:它迫使您在几个调用中绘制它,同时更改每个绘制调用之间的绑定缓冲区 如果您的缓冲区很大,可能会起作用 整个缓冲区肯定会上传到GPU。这肯

我必须画一个缓冲区来容纳几千个顶点。我正在使用vbo来存储数据

我知道我必须多次更新VBO,但每次只能更新一小部分

因此,我想知道这样做的最佳方法是:

  • 将VBO拆分为更小的VBO(可容纳300个顶点),然后用一个调用更新单个VBO
  • 一个大型VBO并使用大量的
    glBufferSubData()
    调用
  • 使用
    glMapBuffer()
    和一个大型VBO
  • 听起来不是个好主意:它迫使您在几个调用中绘制它,同时更改每个绘制调用之间的绑定缓冲区
  • 如果您的缓冲区很大,可能会起作用
  • 整个缓冲区肯定会上传到GPU。这肯定会和glBufferData一样高效,但您可以异步执行
    如果您的缓冲区较小,则认为glBufferData或glMapBuffer是更好的解决方案<代码>100000*sizeof(浮点)*3~=1MB。这应该没有问题。

    还有另一个选项,有点像选项3-使用一个大的VBO(可能使用
    GL\u STREAM\u DRAW
    模式)重置每个帧(通过调用
    glBufferData
    ,每次使用
    NULL
    缓冲指针和相同大小),然后立即执行
    glMapBuffer
    -ed。缓冲区在填充时保持映射状态,然后在绘图前取消映射。重复一遍

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

    这种方法似乎是
    vertex\u buffer\u对象
    扩展正式认可的方法。请参见“使用映射缓冲区对象的顶点阵列”示例:


    这表明OpenGL(或驱动程序?)将关注这种行为,并(在发现时)安排事情以便高效地执行。

    旁注:我已经知道我必须在几个调用中绘制它-无论我是否使用许多VBO。我也知道我一次只画一部分顶点。更改绑定的VBO缓冲区会有很多开销吗?此外,mapBuffer是否比bufferdata慢?mapBuffer的优点是,当GL执行其他操作时,您可以在缓冲区内复制数据。另一方面,缓冲区映射的实际性能实际上取决于实现。如果您可以避免多次更改VBO,我建议您这样做。