Raúl
Raúl

Reputation: 21

My array for particles isn't working (C++/Particle System)

I am trying to make a simple particle system to make a smoke effect for a tire & wheel I made in opengl. After searching, I found particle systems can be used for this. I've never made a particle system so I tried to see if I could find any online that I could just modify for my specific purpose but no luck so here I am trying to make my own.

I have a framework that allows me to make only one particle that is made from where I click on the screen. After being made, the particle will just fall down off screen. I was then able to modify the code to then be able to make 2 show up by copying and pasting the code I used to make the first single one(but just changing the variable name). From this I then knew I could make as many particles as I want with a for loop and an array(at least I think I could). However, it doesn't really do what I was hoping. Before doing this, I had only two particles that would appear after I would click anywhere on the screen. Now, after implementing my array of particles, I removed the second particle(as shown in code below) and replaced it with my array. MAX_PARTICLES is only set to 5 just to test it. Yet, only one particle shows and it also doesn't move... It is stuck at the spot where I clicked for the particles to appear from.

Here is a picture of what it was before making an array for particles.

Here is a picture of what it is now after making an array for particles.

I don't understand why it is that only one particle of the array shows and also why it doesn't move. My assumption is the g.particle address is not being accessed in my movement() or my render(). But I don't know how to fix it. Below is my code for movement() and also render().

 void movement()
 {
     if (g.n <= 0)
         return;
     Particle *p = &g.particle;
     p->s.center.x += p->velocity.x;
     p->s.center.y += p->velocity.y;

     //this commented code is me making another particle
     /*Particle *b = &g.particles[0];
     b->s.center.x += b->velocity.x;
     b->s.center.y += b->velocity.y;*/

     Particle b[MAX_PARTICLES];
     for(int i=0; i<MAX_PARTICLES; i++)
     {
         b[i] = g.particles[i];
         b[i].s.center.x += b[i].velocity.x;
         b[i].s.center.y += b[i].velocity.y;
     }

     //check for off-screen
     if (p->s.center.y < 0.0) {
         cout << "off screen" << endl;
         g.n = 0;
     }   
 }

 void render()
 {
     glClear(GL_COLOR_BUFFER_BIT);
     //Draw shapes...
     //draw the box
     Shape *s;
     glColor3ub(90,140,90);
     s = &g.box;
     glPushMatrix();
     glTranslatef(s->center.x, s->center.y, s->center.z);
     float w, h;
     w = s->width;
     h = s->height;
     glBegin(GL_QUADS);
     glVertex2i(-w, -h);
     glVertex2i(-w,  h);
     glVertex2i( w,  h);
     glVertex2i( w, -h);
     glEnd();
     glPopMatrix();
     //
     //Draw particles here
     if (g.n > 0) {
         //There is at least one particle to draw.
         glPushMatrix();
         glColor3ub(150,160,220);
         Vec *c = &g.particle.s.center;
         w = h = 2;
         glBegin(GL_QUADS);
         glVertex2i(c->x-w, c->y-h);
         glVertex2i(c->x-w, c->y+h);
         glVertex2i(c->x+w, c->y+h);
         glVertex2i(c->x+w, c->y-h);
         glEnd();
         glPopMatrix();

         /*below code is commented out because it was just me 
         trying to make another particle.*/

         //second particle
         /*glPushMatrix();
         glColor3ub(150,160,220);
         Vec *d = &g.particles[0].s.center;
         w = h = 2;
         glBegin(GL_QUADS);
         glVertex2i(d->x-w, d->y-h);
         glVertex2i(d->x-w, d->y+h);
         glVertex2i(d->x+w, d->y+h);
         glVertex2i(d->x+w, d->y-h);
         glEnd();
         glPopMatrix(); */


         //making a for loop to draw all the particles.
         for(int i=0; i<MAX_PARTICLES; i++)
         {
             glPushMatrix();
             glColor3ub(150,160,220);
             Vec *d = &g.particles[i].s.center;
             w = h = 2;
             glBegin(GL_QUADS);
             glVertex2i(d->x-w, d->y-h);
             glVertex2i(d->x-w, d->y+h);
             glVertex2i(d->x+w, d->y+h);
             glVertex2i(d->x+w, d->y-h);
             glEnd();
             glPopMatrix(); 
         }
     }

As shown, I basically took the given code for making a single particle and tried to make an array that makes 5 particles at once. Just in case there is a problem with how I make the particles, here the code for that as well, for you all to check:

 void makeParticle(int x, int y)
 {   
     //Add a particle to the particle system.
     // 
     if (g.n >= MAX_PARTICLES)
         return;
     cout << "makeParticle() " << x << " " << y << endl;
     //set position of particle
     Particle *p = &g.particle;
     p->s.center.x = x;
     p->s.center.y = y;
     p->velocity.y = -4.0;
     p->velocity.x =  1.0;

     /*Particle *v = &g.particles[0];
     v->s.center.x = x;
     v->s.center.y = y;
     v->velocity.y = -5.0;
     v->velocity.x =  1.0; */

     float vy = -5.0;
     for(int i=0; i<MAX_PARTICLES; i++)
     {
         Particle *v = &g.particles[i];
         v->s.center.x = x;
         v->s.center.y = y;
         v->velocity.y = vy;
         v->velocity.x =  1.0;
         vy--;
     }
     ++g.n;
 }

Please help me out figure out what I did wrong that isn't allowing me to properly make the particles using an array. I have a feeling it's just I'm not accessing g.particles correctly.

Upvotes: 0

Views: 317

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409482

When you do

b[i] = g.particles[i];

you copy the object into the array b. All the changes you make to b[i] will be on that object only.

As I see it the array b isn't actually needed, all you need is a reference to the object g.particles[i]:

Particle& b = g.particles[i];
b.s.center.x += b.velocity.x;
b.s.center.y += b.velocity.y;

Upvotes: 3

Related Questions