I've combined all of my vertex data for many particles into a single array. How would I batch draw all of those particles in a manner that preserves their unique translations?
I am so confused as to how to do this. I've already created two posts on this issue but am still confused. I am currently using OpenGL ES 1.1 but am willing to upgrade to 2.0 if that means I can actually accomplish batch rendering of particles with unique translations, rotations, etc.
The two posts are:
- OpenGL ES - How to Batch Render 500+ particles w/ different alphas, rotations, and scales?
- How do I draw 1000+ particles (w/ unique rotation, scale, and alpha) in iPhone OpenGL ES particle system without slowing down the game?
Both explain a high level approach, but I need to know how to render this batch of particles where each particle's translation, rotation, and scale will change every frame. If your answer is to compute the translations on the CPU, then please show an example of this.
I am currently using Vertex Array Objects in my implementation. I undertstand I should be using VBO's for best performance. I will implement VBO's, but first I want to implement the batching. Once I finish the successful batching, I will change the VAO's to VBO's. Hence, the focus of this question is how to accomplish this with VAO's.
Here was my code before batching, where I would push a new matrix in the modelview matrix, translate, rotate, scale, and alpha according to the current Actor being rendered, and draw the vertices and textureCoords of the current Actor being rendered:
glPushMatrix();
glTranslatef(translation.x, translation.y, translation.z);
// rotation
glRotatef(rotation.x, 1, 0, 0);
glRotatef(rotation.y, 0, 1, 0);
glRotatef(rotation.z, 0, 0, 1);
// scale
glScalef(scale.x, scale.y, scale.z);
// color and alpha
glColor4f(1.0, 1.0, 1.0, alpha);
glVertexPointer(2, GL_FLOAT, 0, aSprite.vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texturedQuad.textureCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
Now, given that I've combined the vertices and textureCoords of all particle Actors into batch arrays, I would like to push a new matrix in the modelview matrix, and draw the vertices and textureCoords of those Actors at their appropriate translations, rotations, scales, alphas, etc..
So my guess is it would look soemthing like:
static GLFloat verticesBatched[appropriate_length] = ...; // I have a method to populate this array based on the Actors to render
static GLFloat textureCoordsBatched[appropriate_length] = ...; // I have a method to populate this array based on the Actors to render
glPushMatrix();
// perform CPU matrix manipulation to manually translate, rotate, and scale all vertices
glVertexPointer(2, GL_FLOAT, 0, verticesBatched);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, textureCoordsBatched);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
A valid answer is one with a code example which clearly illustrates the solution to this question.