I had a bug that took me quite some time to fix. I kept getting EXC_BAD_ACCESS and a reference to a memmove error without any further description until I commented the following line:
[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);
I thought binding a buffer to 0 meant unbinding it, so I really cant understand how would that made my app crash.
Thanks for the information! I just do not stay with this concern...
My structures:
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
};
From your code, it looks as if this function is in some initialization routine, where you initialize your attribute data, which gets stored in the bound VAO, so that when drawing you only need to bind the VAO.
A VAO in turn encapsulates all the state needed for drawing VBOs, which is the enabled flags of your attributes (set by
gl(En/Dis)ableVertexAttribArray
), the attribute sources and properties (set withglVertexAttribPointer
), and the currently bound index buffer (set withglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)
). Note that it doesn't store the currently bound vertex buffer, as this information is stored in the attribute state.So what happens is, that you create and bind the index buffer, set its data, then unbind it, with the VAO still active. So the VAO state will store a
GL_ELEMENT_ARRAY_BUFFER
binding of0
. When you now draw something withthere is no buffer bound and the
glDrawElements
fails, as VAOs don't work with client side arrays. You either have to use a VBO for the index data or draw non-indexed primitives (withglDrawArrays
).Neither will
work, because the bound index buffer is overwritten by the VAO when it gets bound (whose index buffer is
0
). It would work if you first bind the VAO and then the index buffer, but that would only circumvent the problem.Conceptually the bound
GL_ELEMENT_ARRAY_BUFFER
is part of the VAO state, so you should not bind it to0
in your VAO initialization routine (only if you don't need any index data). And neither are you allowed to use client side arrays for index or vertex data when using VAOs. If you don't want to draw indexed geometry though, just useglDrawArrays
instead ofglDrawElements
, but then the index buffer is obsolete, anyway.