I am using Vertex Buffer Object (VBO) in OpenGL ES 2.0.
I have a vertex dataset that is permanently stored in regular RAM. The reason is that calculating vertex positions from scratch is expensive, but a delta can be added to the last position to update it cheaply.
The actual number of vertices to be drawn changes rapidly over time. In one frame I can have 1000 and in the next 2500. Following the tips I got here earlier, I now specify integer UPPER as the upper bound on the number of vertices that will ever be drawn. I malloc arrays of vertices and indexes of arrays only once at startup based on this value.
I pass the prompt GL_STREAM_DRAW for each glBindBuffer call to indicate that the data is changing every frame.
Trying to be as efficient as possible, I created the following setup:
// SETUP: Called only once. glBindBuffer(GL_ARRAY_BUFFER,...); glBufferData(GL_ARRAY_BUFFER,...); // Pass vertex data for UPPER vertices. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...); glBufferData(GL_ELEMENT_ARRAY_BUFFER,...); // Pass index values 0 - (UPPER-1). glEnableVertexAttribArray(...); // Setup vertex attributes. glVertexAttribPointer(...); glUseProgram(...); // Use program with custom shaders. glUniformMatrix4fv(...); // Identify shader uniforms. // UPDATE: Called when vertex data changes (on each frame). glBindBuffer(GL_ARRAY_BUFFER,...); glBufferSubData(GL_ARRAY_BUFFER,...); // Update VBO data. // RENDER: Called on each frame. glDrawElements(GL_TRIANGLES, numberOfVerticesThisFrame, ...); // Number of vertices and indices to be used is inherently specified in here.
However, this breaks down from EXC_BAD_ACCESS to glDrawElements , and I know this because of my ordering of the gl commands.
I had a similar installation that previously worked:
// UPDATE: Called when vertex data changes (on each frame). glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...); glBufferData(GL_ELEMENT_ARRAY_BUFFER,...); // Pass index values 0 - (actual number of vertices to draw - 1) // RENDER: Called on each frame. glBindBuffer(GL_ARRAY_BUFFER,...); glBufferData(GL_ARRAY_BUFFER,...); // Pass vertex data for actual number of vertices (not UPPER). glEnableVertexAttribArray(...); // Setup vertex attributes. glVertexAttribPointer(...); glUseProgram(...); // Use program with custom shaders. glUniformMatrix4fv(...); // Identify shader uniforms. glDrawElements(GL_TRIANGLES, numberOfVerticesThisFrame, ...);
However, this installation requires a lot more work for each frame, and as you can see, this is due to the resizing of the VBO (since it uses the actual size, not UPPER ), which I was told is a big performance gap.
Can someone explain to me any obvious problems with my new setup, and most importantly, which commands should I call each frame before glDrawElements ? My assumption that I can prepare all possible indexes in advance and then pass the actual number of vertices to glDrawElements is clearly wrong.