【问题标题】:Is "glGenBuffers" really important if we have glBindBuffer?如果我们有 glBindBuffer,“glGenBuffers”真的很重要吗?
【发布时间】:2019-04-06 19:56:32
【问题描述】:

好吧,我从 OpenGL 开始,通过阅读有关 glBindBuffer 的文档,我有点困惑。

"glBindBuffer 将缓冲区对象绑定到指定的缓冲区绑定点。调用 glBindBuffer 并将 target 设置为可接受的符号常量之一和 buffer 设置为缓冲区对象的名称将该缓冲区对象名称绑定到目标。如果不存在名称为 buffer 的缓冲区对象,则为“ 来源:http://docs.gl/gl4/glBindBuffer

这是否意味着如果我不创建名称为“foo”的缓冲区对象,但我调用 glBindBuffer,它会为我创建一个名称为“foo”的缓冲区对象(“foo”)?

如果是这样,下面的代码应该可以正常工作:

GLuint bar = 70;
glBindBuffer(GL_ARRAY_BUFFER, bar);

-> 创建缓冲区对象,将其与 bar (70) “连接”并将其绑定到 GL_ARRAY_BUFFER。

【问题讨论】:

  • 您需要将名称视为黑盒子,而不是整数。假设它们是非常复杂的不透明值,因此您想让 OpenGL 在所有情况下为您生成它们。

标签: opengl


【解决方案1】:

不,此代码仅适用于兼容性配置文件上下文(或 OpenGL ES)。

OpenGL 4.6 API Core Profile Specification - 2.6.1 Object Management- page 28

[...] GenBuffers 命令返回一个或多个以前未使用的缓冲区对象名称。
生成的名称由 GL 标记为已使用,仅用于名称生成。以这种方式标记的对象名称不会被其他调用返回以生成相同类型的名称,直到通过删除它们再次将名称标记为未使用 [...]

这意味着glGenBuffers 除了保留名称(值)之外什么也不做。对glGenBuffers 的进一步调用将不会返回相同的值。 如果glGenBuffers 始终用于获取缓冲区对象的名称值,那么您可以确定该值尚未用于其他缓冲区对象。

但在桌面 OpenGL 核心配置文件规范中,不允许使用 glBindBuffer 的名称,glGenBuffers 未保留(返回)该名称。

OpenGL 4.6 API Core Profile Specification - 6.1 Creating and Binding Buffer Objects - page 62

如果缓冲区不是零或名称,则会生成 INVALID_OPERATION 错误 从先前对 GenBuffers 的调用返回,或者如果这样的名称已经 用 DeleteBuffers 删除。

OpenGL 4.6 API Compatibility Profile Specification - 6.1 Creating and Binding Buffer Objects - page 62 中缺少这部分规范

这有点令人困惑,但这就是规范。

此行为可通过您问题的代码进行验证。以下代码使用兼容性配置文件上下文不返回错误,但使用核心配置文件上下文返回 GL_INVALID_OPERATION

GLuint bar = 70;
glBindBuffer(GL_ARRAY_BUFFER, bar); 
GLenum error = glGetError();

【讨论】:

  • 那么,要编写代码而不使用glGenBuffers,我猜你需要自己分配ID? int lastBuffer = 1; glBindBuffer(GL_ARRAY_BUFFER, lastBuffer++); ?
  • @Rabbid76 所以我需要先用glGenBuffers 创建对象(也就是保留它),然后我可以用glBindBuffer 使用它,如果我只使用“随机名称”它可能会,或者它可能不起作用,具体取决于该对象是否标记为“未使用”。正确的? (总而言之:只要走安全路径​​:glGenBuffers -> glBindBuffer -> 做其他事情)
  • @Danijel 您可以在应用程序的开头保留一堆名称,并在需要缓冲区时自行管理。
【解决方案2】:

第 6.1 节中的 OpenGL 4.6 Spec 状态指出,当缓冲区未指向先前由 glGenBuffers 保留的名称时,glBindBuffer 必须抛出 GL_INVALID_OPERATION 异常:

如果缓冲区不是零或名称,则会生成 INVALID_OPERATION 错误 从先前对 GenBuffers 的调用返回,或者如果这样的名称已经 用 DeleteBuffers 删除。

official docs 中说明了相同的信息。

我不确定为什么 docs.GL 没有说明该信息。可能是我们以错误的方式解释了该句子,因为它声明缓冲区已创建。从技术上讲,调用glGenBuffers 只会创建缓冲区名称,但在第一次绑定名称时会创建缓冲区对象。

【讨论】:

  • 你说得对,这就是与 OpenGL ES 相比的区别。
  • @Rabbid76:有趣,不知道 glBindBuffer 在 ES 中的行为不同。但这或许可以解释为什么 docs.GL 会声明错误的信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
相关资源
最近更新 更多