Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

From my understanding of what glBindVertexArray does and how it works, the following code should work fine:

First init:

    glGenVertexArraysOES(1, &_vertexArray);
    glBindVertexArrayOES(_vertexArray);

    glGenBuffers(1, &_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, _buffer);
    glBufferData(GL_ARRAY_BUFFER, kMaxDrawingVerticesCount*sizeof(GLKVector3), NULL, GL_DYNAMIC_DRAW);

    glGenBuffers(1, &_indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, kMaxDrawingVerticesCount*1.5*sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLKVector3), BUFFER_OFFSET(0));

    glBindVertexArrayOES(0);

And later add new geometry:

glBindVertexArrayOES(_vertexArray);
glBufferSubData(GL_ARRAY_BUFFER, 0, (GLintptr)_data.vertices.length, _data.vertices.bytes);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, (GLintptr)_data.indices.length, _data.indices.bytes);
glBindVertexArrayOES(0);

However, it doesn't work (there is screen output, but it looks like the buffers were changed between each other). Binding the vertex array is not enough for the vertex/indices buffer to get bound? Because, if I do this:

glBindVertexArrayOES(_vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, _buffer); <-- note this line
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); <-- note this line

glBufferSubData(GL_ARRAY_BUFFER, 0, (GLintptr)_data.vertices.length, _data.vertices.bytes);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, (GLintptr)_data.indices.length, _data.indices.bytes);
glBindVertexArrayOES(0);

Everything works/looks as expected. I find it strange, since the vertex array should have taken care of the buffer binding. Otherwise, what's the purpose to have a vertex array if you still have to bind all the buffers?

share|improve this question

3 Answers 3

up vote 2 down vote accepted

The behavior you're seeing is correct. Consider the case where you're using two vertex streams:

glBindVertexArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 1);
glVertexAttribPointer(...);
glBindBuffer(GL_ARRAY_BUFFER, 2);
glVertexAttribPointer(...);
glBindVertexArray(0);

Now what? The VAO was designed to store whole arrays of bindings, specifically for drawing. It can't substitute for buffer binding semantics in functions that modify buffer state, because it's not clear which buffer should be bound. The first? The last?

Bind the VAO to draw. Bind the VBO to modify the VBO.

share|improve this answer
    
Makes perfect sense, thank you so much for making this clear. –  Meda Feb 20 '13 at 23:36
glBindBuffer(GL_ARRAY_BUFFER, _buffer); <-- note this line

What about it? As has been stated many, many times before, the association between a buffer object and a vertex array is made by glVertexAttribPointer, not by glBindBuffer. Therefore, if you want to change that association, you must bind the buffer and call glVertexAttribPointer. Because that is what gets stored in the VAO.

share|improve this answer
    
Thank you, the first answer you linked is very good. –  Meda Feb 20 '13 at 23:40

If you're having errors, maybe this

glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, (GLintptr)_data.indices.length, _data.indices.bytes);

is incorrect. glBufferSubData requires size in bytes. You haven't allocated the buffer size explicitly as bytes so i'm guessing that sending just the length is not intentional.

EDIT:

Another thing is, you're using OpenGL ES2 and AFAIK it doesn't have VAOs, is that an extension? Are you sure that it's working properly?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.