gpt4 book ai didi

c++ - OpenGL 3 : glBindVertexArray invalidates GL_ELEMENT_ARRAY_BUFFER

转载 作者:可可西里 更新时间:2023-11-01 18:19:06 24 4
gpt4 key购买 nike

我确信如果您通过 glBindBuffer() 绑定(bind)一个缓冲区,您可以安全地假设它保持绑定(bind)状态,直到目标通过另一次调用 glBindBuffer() 。因此,当我发现调用 glBindVertexArray() 会将绑定(bind)到 GL_ELEMENT_ARRAY 目标的缓冲区设置为 0 时,我感到非常惊讶。

这是最小的 C++ 示例代码:

GLuint buff;
glGenBuffers(1, &buff);
std::cout << "Buffer is " << buff << "\n";
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buff);
GLuint vao;
glGenVertexArrays(1, &vao);

GLint bound_buff;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &bound_buff);
std::cout << "Bound before glBindVertexArray: " << bound_buff << "\n";

glBindVertexArray(vao);
// ^- an implicit glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); ?

glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &bound_buff);
std::cout << "Bound after glBindVertexArray: " << bound_buff << "\n";

我在初始化 OpenGL 3.2 设备上下文后立即运行此代码并获得以下输出:

 Buffer is 1
Bound before glBindVertexArray: 1
Bound after glBindVertexArray: 0

另一方面,调用不会更改 GL_ARRAY_BUFFER。我检查了 OpenGL 3.2 规范 (2.10) 中的 glBindVertexArray,但没有提到这种意想不到的副作用。

  1. 此行为是否符合规范?
  2. 如果是这样,调用 glBindVertexArray 会产生哪些其他副作用?
  3. 这背后的基本原理是什么?

我在装有 296.10 WHQL 驱动程序的 Win XPx64 机器上的 nvidia 卡上对此进行了测试。使用 nvidia GT330M 在 OS X Lion 上进行的快速测试给出了相同的结果。

最佳答案

Vertex Array Objects封装渲染顶点数据所需的所有状态*。因此,它们必须封装哪些缓冲区与属性(通过 glVertexAttribPointer)、GL_ELEMENT_ARRAY_BUFFER(glDrawElement* 调用需要)等关联。

However, I still feel a little puzzled by the fact that I couldn't find any mention of this side-effect in the docs.

规范清楚地解释了这一点,但需要了解规范的工作原理才能了解。

OpenGL 是状态的集合,这意味着所有 OpenGL 函数(除了那些实际渲染某些东西的函数)都会修改 OpenGL 状态。当您调用 glVertexAttribPointer 时,此函数在概念上会修改某些内部 OpenGL 状态。

OpenGL objects由它们封装的 OpenGL 状态片段定义。因此,如果一个函数修改了对象封装的状态,那么该函数也会修改对象本身。绑定(bind)对象意味着用该对象的当前状态替换它们封装的当前状态片段。

ARB_vertex_array_object规范根据封装的状态定义 VAO。它基本上指向一个 OpenGL 状态表并说,“VAO 就是所有这些。”此功能的核心 3.x 版本实际上修改了状态表以使其更加清晰(相同的行为,略有不同的解释):

OpenGL 3.3 specification, section 2.10:

The resulting vertex array object is a new state vector, comprising all the state values listed in tables 6.4 and 6.5.

我不会重印表 6.4 和 6.5;你可以自己查一下。但它们显然包括 GL_ELEMENT_ARRAY_BUFFER_BINDING 和各种 GL_VERTEX_ATTRIB_ARRAY_BUFFER_BIDNING(它们是缓冲区对象)。

* 注意:VAO 不包含 glVertexAttrib 设置的状态功能。如果未启用属性数组,这些可能会影响渲染。

关于c++ - OpenGL 3 : glBindVertexArray invalidates GL_ELEMENT_ARRAY_BUFFER,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10000776/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com