Problem with Particlesystem

Started by penguin, May 01, 2011, 12:43:50

Previous topic - Next topic

penguin

Hello,

I wrote a little 3D Engine with a particlesystem, but there is a problem.
Under Linux it runs fine, particle system works and other objects get displayed correct.

But under Windows the particlesystem and two lines drawn in the same function that i added for debugging does not get drawn.
Other objects get drawn correctly.

I use the particle engine like this:
Initialize ist, add it to a objectContainer and add the Container to a Node.
Here are my Sources:

Node.java
package com.iceengine.j3d.container;

/**
 * The Node class manages a world that is build of ObjectContainers.
 * @author penguin
 */
import java.util.ArrayList;
import org.lwjgl.util.vector.Vector3f;
import org.lwjgl.opengl.GL11;

import com.iceengine.j3d.camera.ICamera;

public class Node {
    private ArrayList<ObjectContainer> theObjects;
    private ICamera myCamera;
    int[] fogMode = {GL11.GL_EXP, GL11.GL_EXP2, GL11.GL_LINEAR };

    /**
     * Initializes the node
     * @param theCamera The cameraclass you want to use.
     */
    public Node(ICamera theCamera)
    {
        theObjects = new ArrayList<ObjectContainer>();
        myCamera = theCamera;
    }

    /**
     * Initializes the node.
     */
    public Node()
    {
        theObjects = new ArrayList<ObjectContainer>();
        myCamera = null;
    }

    /**
     * Adds an ObjectContainer to the node.
     * @param toAdd ObjectContainer to add.
     */
    public void addObjectContainer(ObjectContainer toAdd)
    {
        theObjects.add(toAdd);
    }

    /**
     * Draws the Node.
     */
    public void draw()
    {
        Vector3f translation = new Vector3f(0,0,0), rotation = new Vector3f(0,0,0);
        if(myCamera != null)
        {
            translation = myCamera.getTranslation();
            rotation = myCamera.getRotation();
        }

        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        for(int i = 0; i < theObjects.size(); i++)
        {

            theObjects.get(i).drawContainer(translation, rotation);
        }
    }

}


ObjectContainer.java
package com.iceengine.j3d.container;

/**
 * The ObjectContainer class manages a world that is build of Objects.
 * @author penguin
 */
import java.util.ArrayList;
import com.iceengine.j3d.objects.*;
import org.lwjgl.util.vector.Vector3f;
import org.lwjgl.opengl.GL11;

import java.nio.FloatBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class ObjectContainer {
    private ArrayList<IObject> theObjects;
    private Vector3f theTranslation;
    private Vector3f Rotation;
    int[] fogMode = {GL11.GL_EXP, GL11.GL_EXP2, GL11.GL_LINEAR };

    /**
     * Initializes the Container
     * @param translation The translation of the container.
     */
    public ObjectContainer(Vector3f translation)
    {
        theObjects = new ArrayList<IObject>();
        theTranslation = translation;
        Rotation = new Vector3f(0,0,0);
    }

    /**
     * Adds a object that implements IObject to the container.
     * @param toAdd Object to add.
     */
    public void addObject(IObject toAdd)
    {
        theObjects.add(toAdd);
    }

    /**
     * Draws the container.
     */
    public void drawContainer(Vector3f Translation, Vector3f rotation)
    {
        Vector3f translation = theTranslation;
        Vector3f theRotation = Rotation;

        translation = new Vector3f(theTranslation.x+Translation.x,theTranslation.y+Translation.y,theTranslation.z+Translation.z);
        theRotation = new Vector3f(Rotation.x+rotation.x,Rotation.y+(360.0f - rotation.y),Rotation.z+rotation.z);

        for(int i = 0; i < theObjects.size(); i++)
        {
            theObjects.get(i).drawObject(translation, theRotation);
        }
    }

    /**
     * Generates variables for the container.
     */
    private void genObject()
    {
        // What is here todo? :/
    }

    /**
     * Rotate the container in X-Axis
     * @param angle Angle to rotate.
     */
    public void rotateX(float angle)
    {
        Rotation.x = angle;
        genObject();
    }

    /**
     * Rotate the container in Y-Axis
     * @param angle Angle to rotate.
     */
    public void rotateY(float angle)
    {
        Rotation.y = angle;
        genObject();
    }

    /**
     * Rotate the container in Z-Axis
     * @param angle Angle to rotate.
     */
    public void rotateZ(float angle)
    {
        Rotation.z = angle;
        genObject();
    }

    /**
     * Enables lightning in the container.
     */
    public void enableLightning()
    {
        GL11.glEnable(GL11.GL_LIGHTING);
    }

    /**
     * Disables lightning in the container.
     */
    public void disableLightning()
    {
        GL11.glDisable(GL11.GL_LIGHTING);
    }

    /**
     * Sets ambient light in the container.
     * @param ambientLight Lightcolor variables.
     */
    public void setAmbientLight(float[] ambientLight)
    {
        GL11.glDisable(GL11.GL_LIGHT1); // Disable Light1
        ByteBuffer temp = ByteBuffer.allocateDirect(16);
        temp.order(ByteOrder.nativeOrder());
        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_AMBIENT, (FloatBuffer)temp.asFloatBuffer().put(ambientLight).flip());
        GL11.glEnable(GL11.GL_LIGHT1); // Enable Light1
    }

    /**
     * Sets diffuselight in container.
     * @param diffuseLight Lightning color.
     * @param lightPosition Position of the diffuselight.
     */
    public void setDiffuseLight(float[] diffuseLight, float[] lightPosition)
    {
        GL11.glDisable(GL11.GL_LIGHT1); // Disable Light1
        ByteBuffer temp = ByteBuffer.allocateDirect(16);
        temp.order(ByteOrder.nativeOrder());
        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_DIFFUSE, (FloatBuffer)temp.asFloatBuffer().put(diffuseLight).flip());
        GL11.glLight(GL11.GL_LIGHT1, GL11.GL_POSITION,(FloatBuffer)temp.asFloatBuffer().put(lightPosition).flip());
        GL11.glEnable(GL11.GL_LIGHT1); // Enable Light 1
    }

    /**
     * Enables fog in the container.
     * @param fogColor The color of the fog.
     * @param FogMode Mode to draw the fog.
     * @param start Z-Coordinate where the fog starts.
     * @param end Z-Coordinate where the fog ends.
     * @param density Fog density.
     */
    public void enableFog(float fogColor, int FogMode, float start, float end, float density)
    {
        GL11.glClearColor(0.5f,0.5f,0.5f,1.0f);
        GL11.glFogi(GL11.GL_FOG_MODE, fogMode[FogMode]);
        GL11.glFogf(GL11.GL_FOG_COLOR, fogColor);
        GL11.glFogf(GL11.GL_FOG_DENSITY, density);
        GL11.glHint(GL11.GL_FOG_HINT, GL11.GL_NICEST);
        GL11.glFogf(GL11.GL_FOG_START, start);
        GL11.glFogf(GL11.GL_FOG_END, end);
        GL11.glEnable(GL11.GL_FOG);
    }

    /**
     * Disables fog.
     */
    public void disableFog()
    {
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GL11.glClearDepth(1.0f);
        GL11.glDisable(GL11.GL_FOG);
    }
}


ParticleEmitter.java
package com.iceengine.j3d.particles;

/**
 * The particle emitter for the particle engine.
 * @author penguin
 */
import org.lwjgl.util.vector.Vector3f;
import org.lwjgl.util.Color;
import org.lwjgl.opengl.GL11;

import java.util.Random;

import com.iceengine.j3d.objects.IObject;

public class ParticleEmitter implements IObject{
    private Vector3f position;
    private Vector3f Rotation;
    private Vector3f Gravitation;
    private int particleLifetime;
    private Color myColor;
    private Particle[] Particles;
    private Vector3f moveTo;
    private boolean GenerateLifetime;
    private boolean repeat;

    public void drawObject(Vector3f theTranslation, Vector3f rotation)
    {
        Update();
        drawParticles();
    }

    public void rotateX(float angle)
    {
        Rotation.x = angle;
    }

    public void rotateY(float angle)
    {
        Rotation.y = angle;
    }

    public void rotateZ(float angle)
    {
        Rotation.z = angle;
    }

    /**
     * ParticleEmitter constructor
     * @param Position Position of the emitter
     * @param MoveTo Particles move in axes (Vector3f)
     * @param color Particles color
     * @param lifetime Particle's lifetime
     * @param particles Number of particles
     * @param generateLifetime should lifetime get generated?
     * @param Repeat Repeat everytime from 0 or spawn particles anytime?
     */
    public ParticleEmitter(Vector3f Position,Vector3f MoveTo,Vector3f gravitation, Color color, int lifetime, int particles, boolean generateLifetime, boolean Repeat)
    {
        Gravitation = gravitation;
        repeat = Repeat;
        GenerateLifetime = generateLifetime;
        moveTo = MoveTo;
        position = Position;
        myColor = color;
        particleLifetime = lifetime;

        Rotation = new Vector3f(0,0,0);

        Particles = new Particle[particles];


        Random generator = new Random();

        for(int i = 0; i < particles; i++)
        {
            Particles[i] = createParticle();
        }
    }
    /**
     * Updates the particles.
     */
    public void Update()
    {
        for(int i = 0; i < Particles.length; i++)
        {
            Particles[i].Update();
            if(!Particles[i].isParticleAlive())
            {
                if(repeat)
                Particles[i] = createParticle();
            }
        }
    }
    /**
     * Creates a particle with the values given in the constructor.
     * @return A new particle.
     */
    private Particle createParticle()
    {
        float V = (float)(Math.random() * 25);
        float angle = (float)(Math.random() * 360);
        Vector3f velocity = new Vector3f();

        velocity.x = (float)Math.sin(angle) * V * moveTo.x;
        velocity.y = (float)Math.cos(angle) * V * moveTo.y;
        velocity.z = (((float)Math.random() * 10) - 5) / 10 * V * moveTo.z;//generator.nextFloat() % 10)-5) / 10 * V;
        //System.out.println("NEW " + " " + position.x + " " + position.y + " " + position.z + " " + angle + " " + V + " " + velocity.x + " " + velocity.y + " " + velocity.z);
        int life = 0;
        if(GenerateLifetime)
        {
            life = (int)(Math.random() * particleLifetime);
        } else {
            life = particleLifetime;
        }

        return new Particle(life,new Vector3f(Gravitation.x, Gravitation.y, Gravitation.z), new Vector3f(position.x, position.y, position.z),velocity, myColor);
    }
    /**
     * Draws the particles to the screen.
     */
    public void drawParticles()
    {
        GL11.glDisable(GL11.GL_TEXTURE_2D);
        GL11.glBegin(GL11.GL_POINT);

        for(int i = 0; i < Particles.length; i++)
        {
            Particles[i].drawParticle();
        }
        
        GL11.glEnd();
        GL11.glBegin(GL11.GL_LINE);
            GL11.glVertex3f(1.0f,0.5f,10f);
            GL11.glVertex3f(1.0f, 1.0f, 10.0f);
        GL11.glEnd();
        GL11.glEnable(GL11.GL_TEXTURE_2D);


        GL11.glColor4f(1,1,1,1);

        GL11.glBegin(GL11.GL_LINE);
            GL11.glVertex3f(0.0f,0.5f,10f);
            GL11.glVertex3f(1.0f, 0.5f, 10.0f);
        GL11.glEnd();
    }
    /**
     * Tests if work for every particle is done.
     * @return True if the work is done, false if there are any particles alive.
     */
    public boolean isWorkDone()
    {
        boolean workDone = false;
        for(int i = 0; i < Particles.length; i++)
        {
            if(!Particles[i].isParticleAlive())
                workDone = true;
        }
        return workDone;
    }
}


Particle.java
package com.iceengine.j3d.particles;

/**
 * Ice Engine particle class for the particle engine.
 * @author penguin
 */
import org.lwjgl.util.vector.Vector3f;
import org.lwjgl.util.Color;
import org.lwjgl.opengl.GL11;
public class Particle {
    private Vector3f position;
    private Vector3f velocity;
    private Vector3f Gravitation;
    private Color myColor;
    private int lifetime;
    public long startTime;
    private boolean alive;

    /**
     * Particle constructor.
     * @param Lifetime Lifetime for the particle.
     * @param gravity Gravity for calculating positions.
     * @param Position Startposition.
     * @param Velocity Speed of the particles movement.
     * @param color Particle color.
     */
    public Particle(int Lifetime,Vector3f gravity, Vector3f Position, Vector3f Velocity, Color color)
    {
        Gravitation = gravity;
        position = Position;
        lifetime = Lifetime;
        myColor = color;
        velocity = Velocity;

        startTime = System.currentTimeMillis();

        alive = true;
    }
    /**
     * Updates the particles position.
     */
    public void Update()
    {
        if(alive)
        {
            if((System.currentTimeMillis() - startTime) <= lifetime)
            {
                position.x += velocity.x / 250;
                position.y += velocity.y / 250;
                position.z += velocity.z / 250;

                velocity.x *= 0.975f;
                velocity.y *= 0.975f;
                velocity.z *= 0.975f;

                velocity.x += Gravitation.x;
                velocity.y += Gravitation.y;
                velocity.z += Gravitation.z;
            } else {
                alive = false;
            }
        }
    }
    /**
     * Draws the particle to the screen.
     */
    public void drawParticle()
    {
        if (alive)
        {
            GL11.glColor4f(myColor.getRed(), myColor.getGreen(), myColor.getBlue(),0);
            GL11.glVertex3f(position.x, position.y, position.z);
        }
         
    }
    /**
     * Checks if the particle is alive.
     * @return True if it is alive, false if not.
     */
    public boolean isParticleAlive()
    {
        return alive;
    }
}


OpenGL init
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GLU.gluPerspective(45.0f,((float)Width)/((float)Height),0.1f,100.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glClearStencil(0);
        GL11.glLoadIdentity();

        GL11.glShadeModel(GL11.GL_SMOOTH);
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GL11.glClearDepth(1.0f);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glDepthFunc(GL11.GL_LEQUAL);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);


I really don't know whats wrong there, i've tried much things but nothing works.
In the ParticleEmitter.drawObject() function nothing gets drawn.

Are there any windows specific things to do?

Hope someone can help me,
Penguin

penguin

Does no one knows how to fix this problem?

CodeBunny

Well, you have to realize you're kind of plopping a huge chunk of code that is based on an engine architecture we don't know onto the forums. Personally, every time I've been on the forums, I really haven't had time to really look through this. I'll give it a shot, though...

Well, something looks suspicious:
    /**
     * Draws the particle to the screen.
     */
    public void drawParticle()
    {
        if (alive)
        {
            GL11.glColor4f(myColor.getRed(), myColor.getGreen(), myColor.getBlue(),0);
            GL11.glVertex3f(position.x, position.y, position.z);
        }
         
    }


Supplying a 0 for the alpha value makes it totally transparent, and you can't see it.

Conceivably, that's not the issue, because you seem to draw a line that has an alpha of 1. Still, change your supplied alpha value away from 0.

penguin

Tried, to change the alpha value.
Still no changes there.
I'm really confused :S