如果我们有glBindBuffer,"glGenBuffers"真的很重要吗?

Is "glGenBuffers" really important if we have glBindBuffer?

本文关键字:glGenBuffers 我们有 glBindBuffer 如果 真的      更新时间:2023-10-16

好吧,我从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创建的,但缓冲区对象是在名称首次绑定时创建的。