11

我很难理解 VAO 究竟是如何处理缓冲区映射的。我正在做的事情可以用这个伪代码来描述:

SetUp:
  BindVAO
  BindArrayBuffer
  glBufferData(GL_ARRAY_BUFFER, ExpectedMaxCount, NULL, GL_DYNAMIC_DRAW);//Allocate storage
  glEnableVertexAttribArray
  glVertexAttribPointer

  BindElementBuffer
  Allocate storage (no data yet)

  UnbindVAO
  UnbindArrayBuffer
  UnbindElementBuffer

Draw:
  SubArrayAndElementDataIfNeeded
  BindVAO
  DrawElements
  1. 当调用 DrawElements 时,OpenGL 使用绑定的 VAO 来解析数组和元素缓冲区绑定是否正确?在 Draw 调用之后,绑定的数组缓冲区为 0,但元素缓冲区仍然是用于 Draw 的缓冲区。

  2. 在 VAO 设置期间是否必须分配缓冲内存?如果在设置后调用 BufferData,VAO 会失效吗?

4

1 回答 1

17

我很难理解 VAO 究竟是如何处理缓冲区映射的。

在“缓冲区”周围使用“映射”一词时要非常小心;在处理缓冲区对象时具有特定含义,您可能不打算这样做。

当调用 DrawElements 时,OpenGL 使用绑定的 VAO 来解析数组和元素缓冲区绑定是否正确?在 Draw 调用之后,绑定的数组缓冲区为 0,但元素缓冲区仍然是用于 Draw 的缓冲区。

一个与另一个无关。顾名思义,顶点数组对象包含从数组中提取顶点数据所需的所有状态。当你绑定一个时,所有的状态都会回到上下文中。

调用后“绑定数组缓冲区”为 0 的原因是因为调用为 0 。绘图调用不会改变 OpenGL 状态。

此外,你似乎中了GL_ARRAY_BUFFER陷阱。GL_ARRAY_BUFFER绑定只与三个函数有关:、glVertexAttribPointerglVertexAttribIPointerglVertexAttribLPointer看到一个模式?)。这些是查看该绑定的唯一函数。他们所做的是获取在调用这些函数时绑定的缓冲区,并将该缓冲区与当前 VAO 相关联。GL_ARRAY_BUFFER不是VAO 状态一部分。只有当您调用这三个函数之一时,缓冲区对象才会与 VAO 关联。一旦你打了那个电话,你就可以绑定任何你想要的东西GL_ARRAY_BUFFER

GL_ELEMENT_ARRAY_BUFFER VAO 状态的一部分。

在 VAO 设置期间是否必须分配缓冲内存?如果在设置后调用 BufferData,VAO 会失效吗?

从技术上讲不是,但是在缓冲区有存储之前不使用它是一种很好的形式。特别是如果它们是静态缓冲区。

于 2012-09-28T14:58:54.927 回答