Particle Engine

Started by
7 comments, last by _the_phantom_ 12 years, 1 month ago
Hey guys!
I have been wondering, which is the best method for creating a particle system.
Structs or vector containers?
Im just curious because i tried both of them and on a test, My particle engine using structs can render 100000 particles per second, But when i get down to Vectors and iterate over every single particles i could not go over 5000 particles..
I have an Core- i5 processor and using vectors is taking much of my CPU usage.
Anybody ever tried a vector container for particle engines?


struct
{
float x;
float y;
.....
}particles;

//Either using a for loop to access them or vector containter and iterate over them..


Thanks!

EDIT:: Sorry if i am at the wrong forum. Move it if so.
Advertisement
Structs or vector containers?[/quote]
Your term usage of "Struct" does not make sense. Explain what you mean. Vectors hold structs.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

A [font=courier new,courier,monospace]std::vector[/font] and a raw array should both be exactly as fast as each other, if used correctly.

Structs or vector containers?

Your term usage of "Struct" does not make sense. Explain what you mean. Vectors hold structs.
[/quote]
My bad, I meant an array of structs or A vector container.


A [font=courier new,courier,monospace]std::vector[/font] and a raw array should both be exactly as fast as each other, if used correctly
[/quote]
Really? Then i guess im using it wrong because i see a large amount of performance drop.


A [font=courier new,courier,monospace]std::vector[/font] and a raw array should both be exactly as fast as each other, if used correctly

Really? Then i guess im using it wrong because i see a large amount of performance drop.
[/quote]
.reserve as much space as you assume is needed by the particle system early on, -avoid pushing new particles onto it when it's capacity has been reached.
Naturally, never .insert into the vector, and never .remove elements either as it readdresses the vector contents.
Maintain another vector of addresses to empty/unused particle indices, so you can easily resurrect a particle when it's needed at the emission point again.

Ex. [0][1][2][3][4]
particle on index 3 times out/"dies".
push_back on dead-particle-references already with capacity()==particle.size(): [ ][ ][ ][ ][ ]
[3][ ][ ][ ][ ]
I would post your code.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal


class Particle
{
float x;
float y;
float z;
.....
};

Particle particles;
//Either using a vector like
std::vector<Particle> particle;
const int Total_Particles = 100000;
for( int i = 0; i < Total_Particles; i++ )
particle.push_back(particles);

//And then use an
for( std::vector<Particle>::iterator iter = particles.begin(); iter != particles.end(); iter+= 1)
{
iter->x = ...
iter->y = ...
}

//OR using an array of structs
Particle particles[Total_Particles];

//And then using a for loop
for( int i = 0; i < Total_Particles; i++ )
{
particle.x = ...;
particle.y = ...;
}

//I find vectors are a bit slow, But i guess i am using them wrong

Thanks
So this looks like just the initialization and not rendering. I would hope that you are not doing this each frame:
[color="#000088"]for[color="#666600"]( [color="#000088"]int[color="#000000"] i [color="#666600"]= [color="#006666"]0[color="#666600"];[color="#000000"] i [color="#666600"]< [color="#660066"]Total_Particles[color="#666600"];[color="#000000"] i[color="#666600"]++ [color="#666600"])[color="#000000"]
particle[color="#666600"].[color="#000000"]push_back[color="#666600"]([color="#000000"]particles[color="#666600"]);

Also before that loop I posted, you want to do, as suggested, particle.reserve(Total_Particles). A vector IS an array, but it allows growth. So when the array fills up, it creates a new, bigger array, copies the old smaller array into the new bigger one, and allows you to add more elements.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal



//And then use an
for( std::vector<Particle>::iterator iter = particles.begin(); iter != particles.end(); iter+= 1)
{
iter->x = ...
iter->y = ...
}

Thanks


Two comments on this;

1) As you are only iterating pull the 'end' condition out of the loop, that will save the call to 'end' every iteration
2) use '++iter' not 'iter += 1'

The first is likely to gain you more than the second but the second is much better style.

This topic is closed to new replies.

Advertisement