Realmente não há necessidade de armazenar memória para cada partícula e animar cada partícula separadamente. Você pode fazer isso proceduralmente reconstruindo a posição das partículas durante o desenho usando a equação física clássica. s = ut + 1 / 2.at ^ 2
Um exemplo simples (sem aceleração constante de partículas):
void drawExplosion(ExplosionParameters& s)
{
Random rng;
rng.seed(s.startSeed);
glBegin(GL_POINTS);
for (int i = 0; i < s.numParticles; i++)
{
vec3 vel = rng.getRandomVector(-1.0f, 1.0f) * s.explosionSpeed;
float timeBias = rng.getRandom(0, s.particleTimeBias);
vec3 pos = s.explosionCentre + (vel * (s.timeElapsed + timeBias));
glPoint3fv(&pos);
}
glEnd();
}
Então você simplesmente aumenta s.timeElapsed em todas as iterações do seu loop de atualização.
Também é totalmente passível de ser implementado na GPU, liberando assim sua CPU de fazer qualquer trabalho. Uma implementação de gpu pode ser assim:
void drawExplosion(ExplosionParameters& s)
{
//bind Vertex Shader If Not Already Bound();
...
// bindVertexBuffer of Zeroes If Not AlreadyBound();
glVertexPointer(...)
//uploadShaderUniformsForExplosion(s);
glUniform3f(...)
...
glDrawArrays(GL_POINTS, 0, s.numParticles);
}
O shader de vértice da GPU reconstruiria a posição das partículas através da equação da física e os uniformes / constantes passados para ela - exatamente como a versão da CPU.
Para adicionar alguma variação, você pode usar mais explosões simultâneas com parâmetros ligeiramente diferentes, animando cores / alfa, escolhendo diferentes posições iniciais. etc.