如果我们有glBindBuffer,"glGenBuffers"真的很重要吗?
Is "glGenBuffers" really important if we have glBindBuffer?
好吧,我从OpenGl开始,通过阅读有关glBindBuffer的文档,我有点困惑。
"glBindBuffer 将缓冲区对象绑定到指定的缓冲区绑定点。调用 glBindBuffer 时,目标设置为接受的符号常量之一,并将缓冲区设置为缓冲区对象的名称,则会将该缓冲区对象名称绑定到目标。如果不存在具有名称缓冲区的缓冲区对象,则使用该名称创建一个缓冲区对象。当缓冲区对象绑定到目标时,该目标的先前绑定将自动断开。 来源: http://docs.gl/gl4/glBindBuffer
这是否意味着如果我不创建具有"foo"名称的缓冲区对象,但我调用glBindBuffer,它将为我创建一个具有该名称("foo")的缓冲区对象?
如果是这样,以下代码应该可以正常工作:
GLuint bar = 70;
glBindBuffer(GL_ARRAY_BUFFER, bar);
-> 创建缓冲区对象,用 bar (70) "连接"它并将其绑定到GL_ARRAY_BUFFER。
不,此代码仅适用于兼容性配置文件上下文(或 OpenGL ES)。
请参阅 OpenGL 4.6 API 核心配置文件规范 - 2.6.1 对象管理 - 第 28 页
[...]命令GenBuffers返回一个或多个以前未使用的缓冲区对象名称。
生成的名称由 GL 标记为已使用,仅用于生成名称。以这种方式标记的对象名称将不会由其他调用返回以生成相同类型的名称,直到通过删除名称再次标记为未使用[...]
这意味着glGenBuffers
除了保留名称(值)之外什么都不做。对glGenBuffers
的进一步调用将不会返回相同的值。 如果始终使用glGenBuffers
获取缓冲区对象的名称值,则可以确保该值尚未用于其他缓冲区对象。
但是在桌面OpenGL核心配置文件规范中,不允许使用glBindBuffer
的名称,该名称不是由glGenBuffers
保留(返回)的。
请参阅 OpenGL 4.6 API 核心配置文件规范 - 6.1 创建和绑定缓冲区对象 - 第 62 页
如果缓冲区不为零或名称,则生成INVALID_OPERATION错误 从上一次调用 GenBuffers 返回,或者如果这样的名称此后 使用删除缓冲区删除。
OpenGL 4.6 API 兼容性配置文件规范中缺少规范的这一部分 - 6.1 创建和绑定缓冲区对象 - 第 62 页
这有点令人困惑,但这就是规范。
此行为可通过问题代码进行验证。以下代码使用兼容性配置文件上下文不返回错误,但使用核心配置文件上下文返回GL_INVALID_OPERATION
:
GLuint bar = 70;
glBindBuffer(GL_ARRAY_BUFFER, bar);
GLenum error = glGetError();
OpenGL 4.6 规范在第 6.1 节中指出,当缓冲区不指向先前由glGenBuffers
保留的名称时,glBindBuffer
必须抛出GL_INVALID_OPERATION
异常:
如果缓冲区不为零或名称,则生成INVALID_OPERATION错误 从上一次调用 GenBuffers 返回,或者如果这样的名称此后 使用删除缓冲区删除。
官方文档中也说明了相同的信息。
我不确定为什么 docs.GL 没有说明这些信息。可能是我们以错误的方式解释这句话,因为它指出缓冲区已创建。从技术上讲,只有缓冲区名称是通过调用glGenBuffers
创建的,但缓冲区对象是在名称首次绑定时创建的。
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 我们可以访问一个不存在的联盟的成员吗
- 如果编译的源代码是特定于它编译的硬件的,我们如何分发它
- 当使用透明的std函数对象时,我们还需要写空的尖括号吗
- 如何在C++中读取空格分隔的输入 当我们不知道输入的数量时
- 我们可以删除链表中静态内存中的节点吗
- 为什么我们要为avl树实现返回一个指向节点的指针,而不是void函数
- 当我们从/tp地址中添加/减去一个整数时会发生什么
- 当我们为(;;) 写作时,它做了什么?for 循环中的双分号有什么作用?
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 当我们进行一些操作时,应该使用什么'std::string'或'std::stringstream'?
- 我们可以将数据永久保存为数据结构吗?
- 为什么我们将单个或多维数组的大小声明为常量值?
- 为什么我们不能重复使用具有不同模板参数的别名模板标识符?
- 为什么当我们有常量引用时创建临时对象?
- 为什么我们再次从结构对象创建结构变量?
- 为什么我们不编写可以处理C++标识符的汇编器和链接器?
- 当返回类型声明为 ListNode 时,我们是否可以返回 false<T>*
- 我们是否需要为 C++ 中的多个函数初始化多个模板?
- 如果我们有glBindBuffer,"glGenBuffers"真的很重要吗?