PDA

View Full Version : Particles, help controlling direction



neo187
11-16-2011, 04:54 PM
Hello,

I am trying to modify this Digiben sample in order to get the effect of particles that generate from a spot (impact point) and float upwards kind of like the sparks of a fire. The sample has the particles rotating in a circle... I have tried removing the cosine/sine functions and replace them with a normal glTranslate with increasing Y value but I just can't get any real results... could anyone please point out roughly where I should add/modify the translation in this code to obtain that result?




void ParticleMgr::init(){

tex.Load("part.bmp");

GLfloat angle = 0; // A particle's angle
GLfloat speed = 0; // A particle's speed

// Create all the particles
for(int i = 0; i < P_MAX; i++)
{
speed = float(rand()%50 + 450); // Make a random speed

// Init the particle with a random speed
InitParticle(particle[i],speed,angle);

angle += 360 / (float)P_MAX; // Increment the angle so when all the particles are
// initialized they will be equally positioned in a
// circular fashion
}
}





void ParticleMgr::InitParticle(PARTICLE &amp;particle, GLfloat sss, GLfloat aaa)
{
particle.speed = sss; // Set the particle's speed
particle.angle = aaa; // Set the particle's current angle of rotation

// Randomly set the particles color
particle.red = rand()%255;
particle.green = rand()%255;
particle.blue = rand()%255;
}





void ParticleMgr::DrawParticle(const PARTICLE &amp;particle)
{
tex.Use();

// Calculate the current x any y positions of the particle based on the particle's
// current angle -- This will make the particles move in a "circular pattern"
GLfloat xPos = sinf(particle.angle);
GLfloat yPos = cosf(particle.angle);


// Translate to the x and y position and the #defined PDEPTH (particle depth)
glTranslatef(xPos,yPos,PDEPTH);


// Draw the first quad
glBegin(GL_QUADS);

glTexCoord2f(0,0);
glVertex3f(-5, 5, 0);

glTexCoord2f(1,0);
glVertex3f(5, 5, 0);

glTexCoord2f(1,1);
glVertex3f(5, -5, 0);

glTexCoord2f(0,1);
glVertex3f(-5, -5, 0);

glEnd(); // Done drawing quad

// Draw the SECOND part of our particle



tex.Use();

glRotatef(particle.angle,0,0,1); // Rotate around the z-axis (depth axis)
//glTranslatef(0, particle.angle, 0);
// Draw the second quad
glBegin(GL_QUADS);

glTexCoord2f(0,0);
glVertex3f(-4, 4, 0);

glTexCoord2f(1,0);
glVertex3f(4, 4, 0);

glTexCoord2f(1,1);
glVertex3f(4, -4, 0);

glTexCoord2f(0,1);
glVertex3f(-4, -4, 0);

glEnd(); // Done drawing quad

// Translate back to where we began
glTranslatef(-xPos,-yPos,-PDEPTH);

}





void ParticleMgr::run(){


for(int i = 0; i < P_MAX; i++)
{
DrawParticle(particle[i]);

// Increment the particle's angle
particle[i].angle += ANGLE_INC;
}

}


For now I am adding a glPushMatrix(), glTranslate(x, y, z) in the run() function above, right before the loop, with x,y,z as the position of the enemy for placing them on top of the enemy....is that the best place for that?

Thanks for any input!

zeoverlord
11-16-2011, 07:28 PM
Yea this example is a bad one when it comes to particles, a proper particle needs two vectors (float[3]) one that contains the current position and one that contains the motion vector.
And for each frame you add the motion vector multiplied with delta time to the position kinda like this.
ParticlePosition+=ParticleMotion*time;
then you start out with setting a random speed in ParticleMotion, this will make the particles radiate out from the origin

finally you modify the motion vector to change the behavior of the particles like this

ParticleMotion+=-9.82*time; // this adds gravity
ParticleMotion*=1-(0.5*time); // this adds drag or air resistance

doing this will allow you to have much better control over particles.

neo187
11-17-2011, 02:58 AM
Yea this example is a bad one when it comes to particles, a proper particle needs two vectors (float[3]) one that contains the current position and one that contains the motion vector.
And for each frame you add the motion vector multiplied with delta time to the position kinda like this.
ParticlePosition+=ParticleMotion*time;
then you start out with setting a random speed in ParticleMotion, this will make the particles radiate out from the origin

finally you modify the motion vector to change the behavior of the particles like this

ParticleMotion+=-9.82*time; // this adds gravity
ParticleMotion*=1-(0.5*time); // this adds drag or air resistance

doing this will allow you to have much better control over particles.

Thanks, that was really helpful :)