如何在GL_STREAM_DRAW与GL_DYNAMIC_DRAW之间进行选择?

时间:2011-11-26 21:13:55

标签: opengl-es vbo

我正在使用OpenGL ES 2.0,但我认为它与非ES有关:如何知道在创建VBO时选择什么“用法”?

这个特殊的VBO将在完全更新之前使用1到4次,我不确定是否必须选择GL_STREAM_DRAW或GL_DYNAMIC_DRAW。

5 个答案:

答案 0 :(得分:21)

嗯,根据OpenGL API,你应该使用 DYNAMIC_DRAW

STREAM
当数据存储内容被修改一次并且最多使用几次时,你应该使用STREAM_DRAW。

STATIC
当数据存储内容被修改一次并多次使用时,请使用STATIC_DRAW。

DYNAMIC
当数据存储内容被重复修改并多次使用时,请使用DYNAMIC_DRAW。

确保使用glBufferSubData()

更新VBO

答案 1 :(得分:11)

使用标志是一个提示,而不是强制执行。换句话说:如果使用“错误”标志,事情就不会破坏。所以我建议你尝试所有3:STATIC_DRAW,STREAM_DRAW和DYNAMIC_DRAW,然后选择能够提供最佳性能的那个 - 而且它们很可能会结合。

答案 2 :(得分:7)

除了到目前为止给出的答案,虽然它与GLES没有任何直接关系,但我想在ARB_buffer_storage扩展的问题2中粘贴这一位(与桌面GL 4.4一起介绍) :

  

2)新标志不直接映射到参数   glBufferData和一个不能用另一个来表达。是否   那件事?

     

大多数应用程序都会出现usage错误,无论如何它们只是提示。该   标志是必须遵循的硬性规则。他们服务一个   不同的目的。这里的想法是允许实现不   必须再次猜测应用程序并执行较少的跟踪,并且   为应用程序提供更多控制权。我们在中定义BufferData   具有最自由允许标志的BufferStorage术语   (基本上,任何事情都有),但仍然将提示传递给了   实现允许它继续第二次猜测   应用

这些标志的问题一直是每个实现可能对如何优化使用提示所建议的不同路径有不同的想法,并且每个应用程序似乎对这些优化如何工作有不同的期望。

Nvidias桌面GL驱动程序将在调试配置文件中打印它为缓冲区对象做出的一些决定,特别是如果它们存储在客户端RAM中或直接存储在GPU上。在玩这个时,我得到了以下内容:

Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped in HOST memory.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) stored in VIDEO memory has been updated.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped in HOST memory.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) stored in SYSTEM HEAP memory has been updated.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use SYSTEM HEAP memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use SYSTEM HEAP memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).

我在这里做的是使用PBO将纹理更新流传输到GPU,每帧一次更新,通过映射缓冲区。这里的自然选择是使用GL_STREAM_DRAW,但我指定了GL_STATIC_DRAW。驱动程序所做的是最初给我一些VRAM支持的缓冲区,并对我做的前两个更新进行I / O映射。但后来,它改变了主意,并使用了一个客户支持的缓冲区 - 如果我首先要求GL_STREAM_DRAW,那么我将得到完全相同的结果。我们在此处看到的是上面引用文字的second guessing示例。

所有这些都是高度针对具体实施的。这也是上述GL扩展创建的部分原因 - 这将使程序员更多地控制这些事情。但是,据我所知,这个扩展在OpenGL ES领域是不可用的。

答案 3 :(得分:1)

对于IOS,有关VBO的信息在Apple开发者网站中为here。根据他们的文档 GL_DYNAMIC_DRAW and GL_STREAM_DRAW are equivalent.

但我认为你的解决方案更接近于GL_DYNAMIC_DRAW GL_DYNAMIC_DRAW is for vertex buffers that are rendered many times, and whose contents change during the rendering loop.

答案 4 :(得分:0)

如果实际上要在每帧调用glBufferData(),则使用GL_STREAM_DRAW:

glBufferData()完全刷新缓冲区的内容,从而允许opengl进行一些优化,例如让opengl在仍在使用旧数据的情况下上传新数据:Buffer Object Streaming

如果您不打算经常更改缓冲区的内容,则使用GL_STATIC_DRAW

如果要部分更改缓冲区,例如使用glBufferSubData(),则使用GL_DYNAMIC_DRAW。

据我所知,选择错误的选项可能会降低性能,但仅此而已。