绑定到GL_ELEMENT_ARRAY_BUFFER,但未绑定VAO
Binding to GL_ELEMENT_ARRAY_BUFFER with no VAO bound
OpenGL中当前绑定到GL_ELEMENT_ARRAY_BUFFER
目标的缓冲区是顶点阵列对象(VAO)中包含的状态的一部分。根据OpenGL 4.4核心配置文件规范,在没有VAO绑定的情况下尝试更改或访问GL_ELEMENT_ARRAY_BUFFER
似乎是一个错误:
10.4顶点阵列对象
任何命令都会生成
INVALID_OPERATION
错误在没有顶点数组时修改、绘制或查询顶点数组状态已绑定。这发生在初始GL状态,并且可能作为BindVertexArray的结果或DeleteVertexArrays的副作用。
OpenGL wiki的缓冲区对象页面支持这一点:
GL_ELEMENT_ARRAY_BUFFER
表单
gl*Draw*Elements*
的所有呈现函数都将使用指针字段,作为从绑定到此的缓冲区对象开始的字节偏移量目标用于索引呈现的索引将取自缓冲区对象请注意,此绑定目标是"顶点阵列对象"状态的一部分,因此在此处绑定缓冲区之前必须绑定VAO
如果不是这样的话,那就太好了。这将使创建和管理索引缓冲区与任何特定的VAO分开变得容易。但是,如果在没有VAO绑定的情况下,只将缓冲区绑定到GL_ELEMENT_ARRAY_BUFFER
是禁止的,那么唯一的选择是表示索引缓冲区的类在创建/更新它们时绑定伪VAO。
NicolBolas出色的OpenGL教程说,这种类型的使用实际上是有效的:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER)
:在没有VAO绑定的情况下调用此操作不会失败。
这似乎与标准和opengl.org维基相矛盾。标准中是否有我遗漏的支持这一点的内容,或者这只是指不需要使用VAO的兼容性配置文件上下文?
如果您有AMD或NV GPU,您可以始终使用EXT_direct_state_access
扩展操作缓冲区对象,而无需绑定它(这纯粹是一个驱动程序功能,不需要任何特殊类别的硬件)。遗憾的是,尽管英特尔、梅萨和苹果已经存在了5年,但它们并没有费心实施这一延期——懒惰的懒虫。
看看下面的功能,它们会让你描述的更容易:
glNamedBufferDataEXT (...)
glNamedBufferSubDataEXT (...)
glMapNamedBufferEXT (...)
glUnmapNamedBufferEXT (...)
现在,由于DSA的采用率很低,您可能需要为不支持它的系统编写一些后备代码。您可以通过编写具有相同函数签名的函数来复制DSA的功能,这些函数签名使用伪VAO来绑定VBO和IBO,以便在不支持扩展的系统上进行数据操作。在使用VAO之前,您必须跟踪它绑定了什么,并在所述函数返回之前恢复它以消除副作用。
在一个好的引擎中,您应该隐藏VAO绑定状态,而不必从GL查询它。也就是说,您不直接使用glBindVertexArray (...)
,而是实现了一个封装该调用的系统,因此始终知道VAO绑定到特定上下文的内容。最终,这使得在不存在驱动程序支持的情况下模拟DSA功能更加高效。如果您尝试这样的操作,您需要注意,如果glDelete (...)
函数在当前上下文中绑定,则它会隐式解除绑定(通过绑定0)要删除的对象。
但是,如果在没有VAO绑定的情况下,只将缓冲区绑定到
GL_ELEMENT_ARRAY_BUFFER
是禁止的,那么唯一的选择是表示索引缓冲区的类在创建/更新它们时绑定伪VAO。
对旧问题的新回答,但在不需要VAO(或干扰当前绑定的VAO)的情况下使用索引缓冲区的一种简单方法是将缓冲区绑定到GL_ELEMENT_ARRAY_BUFFER
以外的目标。
例如,代替这个:
glBindVertexArray(vaoID); // ...Do I even have a VAO yet?
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID); // <- Alters VAO state!
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, ...);
--人们可能会这样写:
glBindBuffer(GL_COPY_WRITE_BUFFER, indexBufferID);
glBufferSubData(GL_COPY_WRITE_BUFFER, ...);
(这里我任意使用了GL_COPY_WRITE_BUFFER
,它的存在是为了提供一个临时目标,使缓冲区之间的复制更容易,但大多数其他目标也可以。)
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 在基于范围的for循环中使用结构化绑定声明
- 使用 LuaBridge 将 LuaJIT 绑定到C++会导致"PANIC: unprotected error"
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- 在使用GPU支持编译Tensorflow时,会遇到CUDA_TOOLKIT_PATH未绑定变量
- 视觉studo 2019中的漫画和静态/动态绑定
- 将自由函数绑定为类成员函数
- 将常量指针引用绑定到非常量指针
- 在派生类中绑定非静态模板化成员函数
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 在 openGL 中多次绑定缓冲区
- 定义有趣的宏和正则表达式在Z3 C++绑定
- VBO必须在VAO之后绑定
- 为什么VAO可以使用VBO数据绑定它?
- 绑定到GL_ELEMENT_ARRAY_BUFFER,但未绑定VAO
- 何时为与VAO绑定的What
- vao如何知道哪些vbo/ibo被绑定到它?
- 绑定的VAO问题
- 一个VBO可以绑定多个vao
- 当使用IBO/EBO时,只有当我在创建VAO之后调用glBindBuffer来绑定IBO/EB0时,程序才能工作