为什么将GL_ELEMENT_ARRAY_BUFFER绑定到0会产生一个memmove错误?

我有一个错误,我花了相当一段时间来修复。 我不断收到EXC_BAD_ACCESS和一个引用memmove错误,没有任何进一步的描述,直到我评论以下行:

[self loadShaders];

glGenVertexArraysOES(1, &_vao); glBindVertexArrayOES(_vao); // Vertex Buffer glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); glEnableVertexAttribArray(ATTRIB_VERTEX); glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); glEnableVertexAttribArray(ATTRIB_TEXTURE); glVertexAttribPointer(ATTRIB_TEXTURE, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7)); // Index Buffer glGenBuffers(1, &_indexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER,0); ////////// COMMENTED THIS ONE ////////////// //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);// //////////////////////////////////////////// glBindVertexArrayOES(0); 

我认为绑定一个缓冲区为0意味着解除绑定,所以我真的不能理解,这将使我的应用程序崩溃。

感谢您的信息! 我只是不停留在这个问题上

我的结构:

 const Vertex Vertices[4] = { {{0.75, -1, 0}, {1, 0, 0, 1}, {0.125, 0.833496}}, {{0.75, 1, 0}, {0, 1, 0, 1}, {0.125, 1}}, {{-0.75, 1, 0}, {0, 0, 1, 1}, {0, 1}}, {{-0.75, -1, 0}, {0, 0, 0, 1}, {0, 0.833496}}, }; const GLushort Indices[6] = { 0, 1, 2, 2, 3, 0 }; 

从你的代码看来,这个函数看起来好像是在初始化例程中初始化你的属性数据,这些数据存储在绑定的VAO中,所以在绘制时只需要绑定VAO。

VAO依次封装绘制VBO所需的所有状态,这是您的属性的启用标志(由gl(En/Dis)ableVertexAttribArray ),属性来源和属性(使用glVertexAttribPointer设置) 以及当前绑定的索引缓冲区(用glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...) )。 请注意,它不存储当前绑定的顶点缓冲区,因为此信息存储在属性状态中。

所以会发生的是,你创build和绑定索引缓冲区,设置其数据,然后取消绑定它,VAO仍然活跃。 所以VAO状态将存储GL_ELEMENT_ARRAY_BUFFER绑定为0 。 当你现在画一些东西

 glBindVertexArrayOES(_vao); glDrawElements(...); 

没有缓冲区绑定,并且glDrawElements失败,因为VAO不适用于客户端数组。 您必须为索引数据使用VBO或绘制非索引基元(使用glDrawArrays )。

也不会

 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); glBindVertexArrayOES(_vao); glDrawElements(...); 

因为绑定的索引缓冲区在被绑定时被VAO覆盖(索引缓冲区为0 )。 如果你先绑定VAO然后绑定索引缓冲区,那将会起作用,但这只会绕过这个问题。

从概念上说,绑定的GL_ELEMENT_ARRAY_BUFFER是VAO状态的一部分,所以你不应该在你的VAO初始化例程中将它绑定到0 (只有当你不需要任何索引数据时)。 在使用VAO时,您也不允许使用客户端数组作为索引或顶点数据。 如果你不想绘制索引几何graphics,只需使用glDrawArrays而不是glDrawElements ,但是索引缓冲区已经过时了。