【发布时间】:2017-02-14 01:14:00
【问题描述】:
我知道 EBO 可以绑定到 VAO,这与其他 OpenGL 缓冲区对象不同。我也知道,如果在绑定 EBO 时没有绑定 VAO,则 EBO 绑定到 OpenGL 上下文或全局状态。我的问题是,当您将 EBO 绑定到 VAO,然后解除绑定 VAO,并再次绑定 EBO 时,EBO 是绑定到 VAO、全局状态还是两者都绑定?提前感谢您的帮助。
【问题讨论】:
我知道 EBO 可以绑定到 VAO,这与其他 OpenGL 缓冲区对象不同。我也知道,如果在绑定 EBO 时没有绑定 VAO,则 EBO 绑定到 OpenGL 上下文或全局状态。我的问题是,当您将 EBO 绑定到 VAO,然后解除绑定 VAO,并再次绑定 EBO 时,EBO 是绑定到 VAO、全局状态还是两者都绑定?提前感谢您的帮助。
【问题讨论】:
我知道 EBO 可以绑定到 VAO,这与其他 OpenGL 缓冲区对象不同。
首先,一些术语。
在 OpenGL 中,您不会将一个对象绑定到另一个对象。您将一个对象附加到另一个对象。 “绑定”仅在将对象放入上下文时使用。
当您调用glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...) 时,您将附加缓冲区到当前VAO。是的,我知道函数说“绑定”,它的行为很像常规上下文绑定点,但是 OpenGL 函数说了很多愚蠢的话。将 DSA 等效项称为 glVertexArrayElementBuffer 是有原因的,但看不到“绑定”。
我也知道,如果在绑定 EBO 的时候没有绑定 VAO,那么 EBO 就绑定到了 OpenGL 上下文或者全局状态。
这是对的。在兼容性上下文中,VAO 0 是默认的 VAO 对象。也就是说,glBindVertexArray(0) 是一个有效对象。因此,如果您在绑定 VAO 对象 0 的情况下调用 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...),则您将缓冲区附加到 VAO 0。
在核心上下文中,没有 VAO 0。因此,glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...) 将导致 GL_INVALID_OPERATION 错误。
我的问题是,当您将 EBO 绑定到 VAO,然后解除绑定 VAO,并再次绑定 EBO 时,EBO 是绑定到 VAO、全局状态还是两者?
缓冲区可以附加到任意数量的 VAO。因此,将缓冲区附加到 VAO 0 的事实不会改变它附加到其他 VAO 的事实。
【讨论】:
来自 OpenGL 规范:
缓冲区对象是通过将 GenBuffers 返回的名称绑定到 缓冲目标。通过调用 void [gl]BindBuffer( 枚举目标,uint 缓冲区);目标必须是列出的目标之一 在表中...
绑定一个缓冲区正在描述它将如何使用。例如,使用 target =GL_ELEMENT_ARRAY_BUFFER 您将缓冲区绑定为 EBO。
DrawElements、DrawRangeElements 和 DrawElementsInstanced 源 它们的索引来自名称绑定到 [GL_]ELEMENT_ 的缓冲区对象 ARRAY_BUFFER,
因此,使用了当前绑定的 [elements] 缓冲区。
VAO 存储绑定。当您再次“激活”glBindVertexArray 的 VAO 时,EBO 将再次“自动”绑定。
【讨论】: