OpenGL 3: glBindVertexArray invalidates GL_ELEMENT_ARRAY_BUF
OpenGL 3: glBindVertexArray invalidates GL_ELEMENT_ARRAY_BUFFER
我确信,如果通过glBindBuffer()
绑定缓冲区,则可以安全地假设它保持绑定状态,直到目标通过另一个对glBindBuffer()
的调用反弹。因此,当我发现调用glBindVertexArray()
将绑定到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是,而不是被调用更改。我检查了glBindVertexArray
的OpenGL 3.2规范(2.10),没有发现任何意外的副作用。
- 这种行为是否符合规范
- 如果是的话,呼叫
glBindVertexArray
还会产生什么其他副作用 - 这背后的理由是什么
我在带有296.10 WHQL驱动程序的Win XPx64机器上的nvidia卡上测试了这一点。使用nvidia GT330M在OS X Lion上进行的快速测试给出了相同的结果。
顶点数组对象封装了渲染顶点数据所需的所有状态*。因此,它们必须封装与属性关联的缓冲区(通过glVertexAttribPointer
)、GL_ELEMENT_ARRAY_BUFFER(glDrawElement*
调用所需)等等。
然而,我仍然感到有点困惑,因为我在文档中找不到任何关于这种副作用的提及。
规范清楚地解释了这一点,尽管它需要了解规范是如何工作的。
OpenGL是状态的集合,这意味着所有OpenGL函数(除了那些实际渲染的函数)都会修改OpenGL状态。当您调用glVertexAttribPointer
时,此函数在概念上修改OpenGL内部的某些状态。
OpenGL对象是通过封装OpenGL的哪些状态来定义的。因此,如果一个函数修改了对象封装的状态,那么该函数就会修改对象本身。绑定一个对象意味着用该对象的当前状态替换它们封装的当前状态。
ARB_vertex_array_object规范根据VAO封装的状态定义VAO。它基本上指向OpenGL的一个状态表,并说:"VAO就是所有这些。"这个功能的核心3.x版本实际上修改了状态表,使其更加清晰(行为相同,解释略有不同):
OpenGL 3.3规范,第2.10节:
得到的顶点阵列对象是一个新的状态向量,包括表6.4和6.5中列出的所有状态值。
我不打算重印表6.4和6.5;你可以自己查。但它们显然包括GL_ELEMENT_ARRAY_BUFFER_BINDING
和各种GL_VERTEX_ATTRIB_ARRAY_BUFFER_BIDNING
(它们是缓冲对象)。
*注意:VAO不包含glVertexAttrib
函数设置的状态。如果未启用属性数组,这些可能会影响渲染。
- C++11 中不同类型的对象的 std::array 的替代方案
- constexpr begin of a std::array
- C++如果必须在编译时确定大小,std::array 有什么意义?
- OpenGL VBO Indexing ( How to compute Index Array)
- 标准::unordered_map 中的 std::array 的值初始化
- "Warning: Comma within array index expression"但逗号分隔函数参数
- 确保编译时的特定 std::array 位置
- std::array的长度有大小限制吗?
- 将 std::array 移动到另一个 std::array
- 首先按给定顺序打印所有数字,然后使用 Array 打印所有字符和其他符号
- 为什么 std::shared_ptr 被认为是"heavy"和"expensive",但 std::array "same perfprmance as plain (c-style) arrays
- 将 **float array 从 C++ Dll 传递给 python
- std::bind on statd::array 的运算符 []
- 检查输入 std::array 指针数据是否等于某个常量数组
- 我可以安全地复制矢量<array>吗?
- 解析问题 - 预期的非限定 ID - #include <array> 编译错误
- 如何读/写或遍历 std::array 中的特定元素范围?
- 通过 host() 从 af::array 检索数据会导致错误的数据
- 是否可以使用 std::array 作为 POD 结构的数据容器?
- 如何在C++中传递一个大小未知的 std::array?