Improving performance for a blood rendering

Hi

In my project I was trying to improve my blood splatter system to add pooling. It’s still very simple, but I need to improve it’s performance.

Code:


package warlord.ingame.effects;

import java.util.ArrayList;
import warlord.ingame.world.Block;
import warlord.ingame.world.Tile;
import warlord.opengl.Game;
import warlord.opengl.Logger;
import warlord.opengl.MathHelper;

import static org.lwjgl.opengl.GL11.*;

public class BloodSplatter {
	
	// Each particle is 4x4
	public static float SIZE = 4.0f;
	public static int particlesPerTile = Math.round(Tile.WIDTH / SIZE);
	
	private ArrayList<float[]> particles; // Stores the x, y, alpha, and life
	
	
	public BloodSplatter(Block block){
		particles = new ArrayList<float[]>();
	}
	
	public void update(){
		for(int index = 0; index < particles.size(); index++){
			float[] particle = particles.get(index);
			if(particle.length < 4){
				Logger.print("Particle doesn't have a life. Skipping index " + index);
				continue;
			}
			if(Game.getFloat() < 0.999f){
				continue; // .1% chance of spreading
			}
			setLife(index, getLife(index) - 1);
			addParticle(particle[0] - SIZE, particle[1], getLife(index));
			addParticle(particle[0] + SIZE, particle[1], getLife(index));
			addParticle(particle[0], particle[1] - SIZE, getLife(index));
			addParticle(particle[0], particle[1] + SIZE, getLife(index));
		}
		trimLevels();
	}
	
	public void sprayDeath(float cx, float cy){
		sprayDeath(Math.round(cx), Math.round(cy), 5);
	}
	public void sprayDeath(int cx, int cy, int radius){
		for(int _radius = 0; _radius <= radius; _radius++){
			for(int degree = 0; degree <= 360; degree++){
				float dx = (MathHelper.cos((float)Math.toRadians(degree)));
				float dy = (MathHelper.sin((float)Math.toRadians(degree)));
				addParticle(cx + dx, cy + dy);
			}
		}
	}
	
	public void addParticle(float x, float y){
		particles.add(new float[]{x, y, 1.0f, 30.0f});
	}
	public void addParticle(float x, float y, float life){
		particles.add(new float[]{x, y, 1.0f, life});
	}
	
	public void setLife(int index, float life){
		float[] old = particles.get(index);
		old[3] = life;
		particles.set(index, old);
	}
	public float getLife(int index){
		return particles.get(index)[3];
	}
	
	public void trimLevels(){
		for(int index = 0; index < particles.size(); index++){
			float[] particle = particles.get(index);
			if(particle[3] <= 0.0f){
				// the particle is dead
				particles.remove(index);
			}
		}
	}
	
	public void render(){
		update();
		glBegin(GL_QUADS);
		ArrayList<Float> x = new ArrayList<Float>();
		ArrayList<Float> y = new ArrayList<Float>();
		for(int index = 0; index < particles.size(); index++){
			float[] particle = particles.get(index);
			if(x.contains(particle[0])){
				if(y.contains(particle[1])){
					continue;
				}
			}
			x.add(particle[0]);
			y.add(particle[1]);
			glColor4f(1.0f, 0.0f, 0.0f, 30.0f / particle[3]);
			glVertex2f(particle[0], particle[1]);
			glVertex2f(particle[0] + SIZE, particle[1]);
			glVertex2f(particle[0] + SIZE, particle[1] + SIZE);
			glVertex2f(particle[0], particle[1] + SIZE);
		}
		glEnd();
		glColor3f(1.0f, 1.0f, 1.0f);
	}

}

The blood seems to pool alright and looks okay so far, but when the blood starts to spread and overlap it begins to lag. I will eventually change the rendering but for now in development I’m using immediate mode. Any techniques or ideas to improve performance would be appreciated :slight_smile:

CopyableCougar4