鉴于我们使用OpenGL 4.5或支持GL_ARB_direct_state_access
扩展,我们有新功能glCreateBuffers
。
此函数与glGenBuffers
具有相同的签名,但指定:
返回
n
以前在buffers
中使用的未使用的缓冲区名称,每个缓冲区名称都表示一个新的缓冲区对象,它被初始化,好像它已被绑定到一个未指定的目标
glGenBuffers
具有以下规格:
调用
glGenBuffers
返回的缓冲区对象名称不会被后续调用返回,除非它们首先使用glDeleteBuffers
删除。
因此,glCreateBuffers
返回的任何缓冲区名称将永远不会再次使用,但可以由glGenBuffers
使用。
似乎glCreateBuffers
将始终创建新的缓冲区对象并返回其名称,如果之前没有删除过的缓冲区,glGenBuffers
将只创建新的缓冲区。
添加此功能有什么优势?
什么时候应该使用glCreateBuffers
而不是glGenBuffers
?
附:
我认为这代表glCreate*
添加的所有GL_ARB_direct_state_access
函数
你在这里注意到的是基本上整理API以保持Shader和Program对象创建的一致性。它们总是在一次调用中生成和初始化,并且是以这种方式工作的API的唯一部分。每个其他对象首先使用glGen* (...)
保留,然后通过将保留名称绑定到目标来初始化。
事实上,在GL 3.0之前,允许完全跳过glGen* (...)
并简单地通过在某处绑定一个唯一的数字来创建一个对象。
在GL 4.5中,每种类型的对象都被赋予了glCreate* (...)
函数,该函数在GL 4.5中的单个调用中生成并初始化它们。此方法非常适合直接状态访问,其中修改(在这种情况下创建)对象不需要更改(并可能还原)绑定状态。
当以这种方式使用API时,许多对象需要目标(例如纹理),但缓冲对象用于所有意图和目的无类型。这就是API签名相同的原因。使用此接口创建缓冲区对象时,它将“初始化为好像已绑定到未指定的目标”。这对于GL中的大多数类型的对象来说都是完全无稽之谈;他们需要一个目标来正确初始化它们。
这里的主要考虑因素是您可能希望为GL中的对象创建和设置状态,而不会影响期望绑定到某个目标的对象保持不变的其他代码段。这就是创建Direct State Access的原因,也是这些功能存在的主要原因。
理论上,正如dari指出的那样,通过将缓冲区对象绑定到特定目标来初始化缓冲区对象可能会给驱动程序提供有关其预期用途的提示。我不会放多少钱,但是当调用glBufferData (...)
时,这就像实际使用标志一样;充其量的暗示。
OpenGL 4.5规范 - 6.1创建和绑定缓冲区对象:
通过将GenBuffers返回的名称绑定到缓冲区目标来创建缓冲区对象。通过调用实现绑定
void BindBuffer(枚举目标,uint缓冲区);
target必须是表6.1中列出的目标之一。如果先前尚未绑定名为buffer的缓冲区对象,则GL将创建一个新的状态向量,使用零大小的内存缓冲区进行初始化,并包含表6.2中列出的所有状态和相同的初始值。
所以glGenBuffers
和glCreateBuffers
之间的区别在于,glGenBuffers
只返回一个未使用的名称,而glCreateBuffers
也创建并初始化上述状态向量。
用法:
建议使用glGenBuffers
+ glBindBuffer
,因为
GL可以基于初始绑定对存储位置和布局做出不同的选择。
由于在glCreateBuffers
没有给出初始绑定,因此无法做出这种选择。
glCreateBuffers
没有目标,因为没有键入缓冲区对象。第一个绑定目标仅用作OpenGL中的提示。而Khronos考虑给glCreateBuffers
一个target
参数,但他们决定反对它:
NamedBufferData(以及原始EXT中的相应函数)不包含<target>参数。实现是否可以基于此参数对数据存储的使用做出初始假设。它去了哪里?我们应该带回来吗?
已解决:无需缓冲区的目标参数。 Implemetations [sic]不基于<target>参数进行使用假设。只有一个供应商扩展程序执行AMD_pinned_memory。用于指定缓冲区用法的一致方法的[原文如此]将为BufferStorage的<flags>参数添加新标志。
强调补充说。