http://www.bayninestudios.com/2010/04/particle-system-tutorial-on-android/
Particle
systems are a way to add effects to a game, like an explosion, fire, or
water fountain. They usually don’t interact with each other or the
world around them, to improve performance. Even a simple system can
have 50 particles which are a lot of polygons to do for an effect.
First, you’ll want to start a new Android project and paste in the
simplest GLSurfaceView application from the Google Android Blog.
This is a great starting point for any OpenGL app on Android, I use it
all the time when starting a new OpenGL project. It really helped me
get up and running quickly so I could start learning more about OpenGL
rather than struggle with learning Android and OpenGL at the same time.
First, we need to make a particle object.
The most recent code can be found at Bay Nine Studios on Google Code.
First, we need to make a particle object.
package com.bayninestudios.particlesystemdemo;
import java.util.Random;
public class Particle {
// location
public float x;
public float y;
public float z;
public Particle(Random gen)
{
this.x = gen.nextFloat();
this.y = gen.nextFloat();
this.z = gen.nextFloat();
}
}
Simple particle with an x,y,z coordinate and assigned a random value
between 0 and 1. The local variables are public, rather than using
getters and setters for performance reasons. Now this particle needs to
belong in a system.package com.bayninestudios.particlesystemdemo;
import com.bayninestudios.particlesystemdemo.Particle;
public class ParticleSystem {
private Particle[] mParticles;
private int PARTICLECOUNT = 20;
public ParticleSystem() {
mParticles = new Particle[PARTICLECOUNT];
Random gen = new Random(System.currentTimeMillis());
for (int i=0; i < PARTICLECOUNT; i++) {
mParticles[i] = new Particle(gen);
}
}
}
Simple. Now we have to draw everything. Rather than have a draw
routine for each particle, with an assigned texture and vertexes, I have
one object that gets allocated by the system and drawn. For each draw,
you'll need to do the appropriate translates for the position of the
particle. The ParticleSystem class will need a vertex buffer and index
buffer to define the triangle to draw. I've also added two helper
methods to convert float or short arrays to native order buffers. In
previous Android versions I just used FloatBuffer.wrap(float[]) but
newer versions require the native order buffers.
// for use to draw the particle
private FloatBuffer mVertexBuffer;
private ShortBuffer mIndexBuffer;
public ParticleSystem() {
mParticles = new Particle[PARTICLECOUNT];
Random gen = new Random(System.currentTimeMillis());
for (int i=0; i < PARTICLECOUNT; i++) {
mParticles[i] = new Particle(gen);
}
float[] coords = {
-0.1f,0.0f,0.0f,
0.1f,0.0f,0.0f,
0.0f,0.0f,0.1f};
short[] icoords = {0,1,2};
mVertexBuffer = makeFloatBuffer(coords);
mIndexBuffer = makeShortBuffer(icoords);
}
// use to make native order buffers
private FloatBuffer makeFloatBuffer(float[] arr) {
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
// use to make native order buffers
private ShortBuffer makeShortBuffer(short[] arr) {
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
bb.order(ByteOrder.nativeOrder());
ShortBuffer ib = bb.asShortBuffer();
ib.put(arr);
ib.position(0);
return ib;
}
Also ParticleSystem will need a draw routine. This routine setups the
vertex buffer to use, the color, translates the draw to the location of
the particle, and draws it.
public void draw(GL10 gl) {
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
gl.glColor4f(1f, 1f, 1f, 1f);
for (int i = 0; i < PARTICLECOUNT; i++) {
gl.glPushMatrix();
gl.glTranslatef(mParticles[i].x, mParticles[i].y, mParticles[i].z);
gl.glDrawElements(GL10.GL_TRIANGLES, 3, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
gl.glPopMatrix();
}
}
Finally, in the main ParticleSystemDemo class, create a new
ParticleSystem, initialize the GL perspective and call the draw routine.
class ClearRenderer implements GLSurfaceView.Renderer {
private ParticleSystem mParticleSystem;
public ClearRenderer() {
mParticleSystem = new ParticleSystem();
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLU.gluPerspective(gl, 15.0f, 80.0f/48.0f, 1, 100);
GLU.gluLookAt(gl, 0f, -10f, 15f, 0.5f, 0.0f, 0f, 0.0f, 1.0f, 1.0f);
}
public void onSurfaceChanged(GL10 gl, int w, int h) {
gl.glViewport(0, 0, w, h);
}
public void onDrawFrame(GL10 gl) {
gl.glClearColor(0, 0, .5f, 1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
mParticleSystem.draw(gl);
}
}
After all of this you should have a blue background with a bunch of
triangle particles in the middle of the screen. They don't move yet but
that will be for part two of this. There are other improvements to
make, possibly having the system assign the initial location of the
particle. Randomizing the color. The particle size is hardcoded, and
could be dynamic if needed. Texture mapping the particles. Moving the
particle drawing to a different class, that way there can be multiple
particle models for the same system.
The most recent code can be found at Bay Nine Studios on Google Code.
8 thoughts on “Particle System Tutorial on Android”