Opengl es 如何在总账流式绘图或总账动态绘图之间进行选择?

Opengl es 如何在总账流式绘图或总账动态绘图之间进行选择?,opengl-es,vbo,Opengl Es,Vbo,我使用的是OpenGL ES 2.0,但我认为它也与非ES相关:如何知道在创建VBO时选择什么“用法” 在完全更新之前,此特定VBO将使用1到4次,我不确定是否必须选择GL_STREAM_DRAW或GL_DYNAMIC_DRAW。使用标志是提示,而不是强制。或者换句话说:如果你使用了一个“错误”的标志,事情不会破裂。所以我建议你尝试所有3种:静态绘制、流绘制和动态绘制,并选择一种能给你带来最佳性能的绘制,它们很可能会相互配合。对于IOS,有关VBO的信息在apple开发者网站上。根据他们的文件

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


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

使用标志是提示,而不是强制。或者换句话说:如果你使用了一个“错误”的标志,事情不会破裂。所以我建议你尝试所有3种:静态绘制、流绘制和动态绘制,并选择一种能给你带来最佳性能的绘制,它们很可能会相互配合。

对于IOS,有关VBO的信息在apple开发者网站上。根据他们的文件
GL\u动态图和GL\u流图是等效的。

但我认为你的解决方案更接近GL_DYNAMIC_DRAW
GL\u DYNAMIC\u DRAW用于多次渲染的顶点缓冲区,其内容在渲染循环期间会发生变化。
好吧,根据需要,您应该使用DYNAMIC\u DRAW


当数据存储内容修改一次,最多使用几次时,应使用STREAM_DRAW

静态
当数据存储内容将被修改一次并多次使用时,请使用静态绘制

动态
当数据存储内容将被重复修改和多次使用时,请使用DYNAMIC_DRAW


除了目前给出的答案外,请确保使用

更新VBO,尽管它与GLE没有直接关系,但我想粘贴扩展版第2期中的这一部分(与桌面GL 4.4一起介绍):

2) 新标志不会直接映射到的参数 glBufferData和一个不能用另一个表示。做 那件事

大多数应用程序的用法都是错误的,它们只是提示。这个 旗帜是必须遵守的硬性规定。他们提供服务 不同的目的。这里的想法是不允许执行 必须重新猜测应用程序并执行较少的跟踪,以及 使应用程序具有更多的控制。我们在中定义缓冲区数据 具有最宽松允许标志的缓冲区存储条款 (本质上,任何事情都会发生),但仍然会将提示传递给 实现允许它继续猜测 应用程序

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

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\u STREAM\u DRAW
,但我指定了
GL\u STATIC\u DRAW
。驱动程序最初给了我一些VRAM支持的缓冲区,并对我做的前两次更新进行I/O映射。但是后来,它改变了主意,使用了一个客户端支持的缓冲区——这正好是我当初要求
GL\u STREAM\u DRAW
时得到的结果。我们在这里看到的是上面引用的文本中关于第二次猜测的一个例子


所有这些都是高度特定于实现的。这也是创建前面提到的GL扩展的部分原因——这将给程序员更多的控制权。然而,据我所知,这个扩展在OpenGL ES领域中是不可用的。

GL\u STREAM\u DRAW
如果您要调用
glBufferData()
通常-
glBufferData()
完全刷新缓冲区的内容,允许OpenGL进行一些优化,例如,允许opengl在旧数据仍在使用时上载新数据:

如果您不打算经常更改缓冲区的内容,则使用
GL\u STATIC\u DRAW

如果要部分更改缓冲区,例如使用
glBufferSubData()
,则使用
GL\u DYNAMIC\u DRAW

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


这些选项很可能会影响内存的位置—RAM或VRAM,以及有关使用分配内存的一些策略(先分组写入,然后发送数据,或立即写入)。RAM可由CPU直接写入,但从GPU读取(甚至不考虑修改)的速度较慢,因为它必须通过PCI-e。VRAM是GPU本身上的一个;它不能由CPU直接写入(直到最近,或者除非你是AMD)——相反,GPU上的一个特殊硬件应该将数据从RAM批量复制到VRAM。

这是一个有用的实用技巧,但我仍然想知道这两者的“预期”用途有什么不同。一些GPU可能会利用它。当他们创造了这种区别时,他们可能已经想到了一些可能的优化,否则就没有意义了。这些是什么?@lvella:我认为参考手册对此非常清楚:在“描述”@datenwolf“标题下,这使GL实现能够做出可能显著影响缓冲区对象性能的更智能的决策。”在我看来,这似乎非常不具体且难以捉摸。@bobo:确实如此。事实上,在这么多程序以错误的方式使用它们之后,AMD/ATI驱动程序完全忽略了这一提示,并通过分析程序的行为来选择最佳策略。如果有疑问,我会默认使用DYNAMIC_DRAW。而且OpenGL规范对此也不是很清楚。问题是,必须指定其中一个标志。设置glt的GL_don_CARE标志是非常有意义的