鉴于我们正在使用OpenGL 4.5或支持GL_ARB_direct_state_access
扩展,我们有新功能glCreateBuffers
。
此函数与glGenBuffers
具有相同的签名,但指定:
在
n
中返回buffers
以前未使用的缓冲区名称,每个缓冲区名称表示一个新的缓冲区对象,就像它已绑定到未指定的目标一样
glGenBuffers
具有以下规范:
通过调用
glGenBuffers
返回的缓冲区对象名称不会被后续调用返回,除非它们首先被glDeleteBuffers
删除。
因此,glCreateBuffers
返回的任何缓冲区名称将永远不会再次使用,但可由glGenBuffers
使用。
似乎glCreateBuffers
将始终创建新的缓冲区对象并返回其名称,glGenBuffers
只会创建新的缓冲区,如果之前没有缓冲区已被删除。
添加此功能有什么好处?
我应该何时使用glCreateBuffers
而不是glGenBuffers
?
P.S。
我认为这代表glCreate*
GL_ARB_direct_state_access
函数
答案 0 :(得分:11)
您在此处注意到的是基本上整理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 (...)
时,这就像实际使用标志一样;充其量的暗示。
答案 1 :(得分:5)
OpenGL 4.5规范 - 6.1创建和绑定缓冲区对象:
通过绑定GenBuffers返回的名称来创建缓冲区对象 缓冲目标。通过调用
实现绑定void BindBuffer(枚举目标,uint缓冲区);
目标必须是列出的目标之一 在表6.1中。 如果没有名为buffer的缓冲区对象 在先前绑定的情况下,GL创建一个新的状态向量,用 一个零大小的内存缓冲区并包含所有状态和 表6.2中列出了相同的初始值。
因此glGenBuffers
和glCreateBuffers
之间存在差异,glGenBuffers
仅返回未使用的名称,而glCreateBuffers
也会创建并初始化上述状态向量。
用法:
建议使用glGenBuffers
+ glBindBuffer
,因为
GL可能会对存储位置做出不同的选择 基于初始绑定的布局。
由于在glCreateBuffers
中没有给出初始绑定,因此无法做出此选择。
答案 2 :(得分:1)
glCreateBuffers
没有目标,因为没有键入缓冲区对象。第一个绑定目标仅用作OpenGL中的提示。而Khronos考虑给glCreateBuffers
target
参数,但他们决定反对它:
NamedBufferData(以及原EXT中的相应功能) 不包括< target>参数。实现是否可以 关于基于此的数据存储的使用的初始假设 参数。它去了哪里?我们应该把它带回来吗?
已解决:无需缓冲区的目标参数。的 Implemetations [原文如此] 不要根据< target>进行使用假设。参数。只有一个 供应商扩展这样做AMD_pinned_memory。一致的方法[原文如此] 指定缓冲区用法是为该< flags>添加一个新标志。 BufferStorage的参数。
强调补充。