This was made back when I was first learning LWJGL. I tried to clean it up a bit. It also had tons and tons of testing stuff I was doing that I had to strip out to just have particle stuff haha. It's not very good, just very very simple particle system. This may help you figure out the problem. There's actually a pretty good particle system tutorial/demo somewhere using LWJGL; maybe the ninja cave tutorials?
I was just going to add it as an attachment...but these forums won't let you attach a .java file......oh, the irony
import static org.lwjgl.opengl.GL11.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.LinkedList;
import java.util.ListIterator;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Cursor;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.Log;
/**
* @author jediTofu
*/
public class Particles {
public static void main(String[] args) {
Particles p = null;
try {
p = new Particles();
while(!Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)
&& !Display.isCloseRequested()) {
if(Display.isVisible()) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
p.run();
}
else {
try { Thread.sleep(100); } catch(Exception e) {}
}
Display.update();
Display.sync(100);
}
}
catch(Exception ex) {
ex.printStackTrace();
System.exit(1300);
}
finally {
if(p != null) {
p.destroy();
}
}
}
//lwjgl
public static int HEIGHT = 768;//Display.getDesktopDisplayMode().getHeight();
public static int WIDTH = 1024;//Display.getDesktopDisplayMode().getWidth();
public static boolean IS_FULLSCREEN = false;
public static boolean MOUSE_IS_GRABBED = false;
//particles
public static int MAX_PARTICLES = 1000;
public static int PARTICLE_HEIGHT = 64;
public static int PARTICLE_WIDTH = 64;
public static float PARTICLE_X_FACTOR = 4.0f;
public static float PARTICLE_Y_FACTOR = 4.0f;
public LinkedList<Particle> particleList = new LinkedList<Particle>();
public Texture particleTexture = null;
public int particleX = 0;
public int particleY = 0;
public Particles() throws LWJGLException,FileNotFoundException,IOException {
//progress bar
int progress = 0;
JProgressBar progressBar = new JProgressBar(0,5);
progressBar.setPreferredSize(new Dimension(300,50));
progressBar.setStringPainted(true);
JLabel label = new JLabel("Loading...",JLabel.CENTER);
JPanel panel = new JPanel(new BorderLayout());
panel.add(progressBar,BorderLayout.PAGE_START);
panel.add(label,BorderLayout.CENTER);
JDialog dialog = new JDialog((JDialog)null,"Loading");
dialog.setAlwaysOnTop(true);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.getContentPane().add(panel);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
dialog.toFront();
//lwjgl
label.setText("Setting up LWJGL Display...");
Display.setDisplayMode(findDisplayMode(WIDTH,HEIGHT));
Display.setFullscreen(IS_FULLSCREEN);
Display.setTitle("Particles");
Display.create();
dialog.setLocationRelativeTo(null);
progressBar.setValue(++progress);
label.setText("Setting up LWJGL Keyboard...");
Keyboard.create();
progressBar.setValue(++progress);
label.setText("Setting up LWJGL Mouse...");
Mouse.create();
Mouse.setGrabbed(MOUSE_IS_GRABBED);
progressBar.setValue(++progress);
//opengl
label.setText("Setting up OpenGL...");
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glClearColor(0.0f,0.0f,0.0f,0.0f);
glClearDepth(1.0);
glAlphaFunc(GL_GREATER,0.1f) ;
glEnable(GL_ALPHA_TEST) ;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glViewport(0,0,WIDTH,HEIGHT);
glMatrixMode(GL_MODELVIEW);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0,WIDTH,0.0,HEIGHT,1.0,-1.0);
glMatrixMode(GL_MODELVIEW);
progressBar.setValue(++progress);
//texture
label.setText("Loading Textures...");
particleTexture = TextureLoader.getTexture("PNG",new FileInputStream("particle.png"));
progressBar.setValue(++progress);
dialog.dispose();
}
public void destroy() {
if(particleTexture != null) {
particleTexture.release();
}
Mouse.destroy();
Keyboard.destroy();
Display.destroy();
}
public void drawParticle(float x,float y,float red,float green,float blue,float alpha) {
x -= particleX + (PARTICLE_WIDTH / 2);
y -= particleY + (PARTICLE_HEIGHT / 2);
particleTexture.bind();
//glPushMatrix();
//glTranslatef(x,y,0);
glColor4f(red,green,blue,alpha);
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f(x,y);
glTexCoord2f(1,0);
glVertex2f(x + particleTexture.getTextureWidth(),y);
glTexCoord2f(1,1);
glVertex2f(x + particleTexture.getTextureWidth(),y + particleTexture.getTextureHeight());
glTexCoord2f(0,1);
glVertex2f(x,y + particleTexture.getTextureHeight());
glEnd();
//glPopMatrix();
}
public DisplayMode findDisplayMode(int width,int height) {
return(findDisplayMode(width,height,Display.getDesktopDisplayMode().getBitsPerPixel()));
}
public DisplayMode findDisplayMode(int width,int height,int bpp) {
try {
for(DisplayMode mode: Display.getAvailableDisplayModes()) {
if(mode.getBitsPerPixel() == bpp && mode.getHeight() == height
&& mode.getWidth() == width) {
return(mode);
}
}
}
catch(LWJGLException ex) {
}
return(null);
}
public void run() {
//drawParticle(0,0,1.0f,0.0f,0.0f,1.0f);
for(ListIterator<Particle> it = particleList.listIterator(); it.hasNext();) {
Particle p = it.next();
if(p.isDead()) {
it.remove();
p = null;
}
else {
p.play();
p.age(1.0);
}
}
if(particleList.size() < MAX_PARTICLES
&& (Mouse.getDX() != 0 || Mouse.getDY() != 0)) {
for(int i = 0; i < 40; i++) {
float red=0.0f,green=0.0f,blue=0.0f;
switch((int)(Math.random() * 4.0)) {
case 0: red = (float)Math.random(); break;
case 1: green = (float)Math.random(); break;
case 2: blue = (float)Math.random(); break;
case 3: red = green = blue = (float)Math.random(); break;
}
particleList.add(new Particle
((float)Math.random() / 40.0f
,Mouse.getX()
,Mouse.getY()
,(float)Math.random() + (float)(int)(Math.random() * PARTICLE_X_FACTOR) * ((int)(Math.random() * 2.0) == 0 ? 1 : -1)
,(float)Math.random() + (float)(int)(Math.random() * PARTICLE_Y_FACTOR) * ((int)(Math.random() * 2.0) == 0 ? 1 : -1)
,red,green,blue));
}
}
}
public class Particle {
private float blue;
private float green;
private float lifespan;
private float lifeVelocity;
private float red;
private float x;
private float xVelocity;
private float y;
private float yVelocity;
public Particle(float lifeVelocity,float x,float y,float xVelocity,float yVelocity,float red,float green,float blue) {
this.blue = blue;
this.green = green;
this.lifespan = 1.0f;
this.lifeVelocity = lifeVelocity;
this.red = red;
this.x = x;
this.xVelocity = xVelocity;
this.y = y;
this.yVelocity = yVelocity;
}
// delta is meant for smoother timing, but not using it right now up above
public void age(double delta) {
/*switch((int)(Math.random() * 2)) {
case 0: x -= xVelocity; break;
case 1: x += xVelocity; break;
}
switch((int)(Math.random() * 2)) {
case 0: y -= yVelocity; break;
case 1: y += yVelocity; break;
}*/
x += xVelocity * delta;
y += yVelocity * delta;
lifespan -= lifeVelocity * delta;
if(lifespan < 0.0f) {
lifespan = 0.0f;
}
}
public boolean isDead() {
return(lifespan <= 0.0f || x < (-PARTICLE_WIDTH) || x > WIDTH
|| y < (-PARTICLE_HEIGHT) || y > HEIGHT);
}
public void play() {
/*glColor3f(red * lifespan,green * lifespan,blue * lifespan);
glBegin(GL_POINTS);
glVertex2f(x * lifespan,y / lifespan);
glVertex2f(x,y);
glEnd();*/
//drawParticle(x * lifespan,y / lifespan,red,green,blue,lifespan);
drawParticle(x,y,red,green,blue,lifespan);
}
}
}