Naprawdę nie ma potrzeby przechowywania pamięci dla każdej cząstki i animowania każdej cząstki osobno. Możesz to zrobić proceduralnie, odtwarzając położenie cząstki podczas rysowania, używając klasycznego równania fizyki. s = ut + 1 / 2.at ^ 2
Prosty przykład (bez stałego przyspieszania cząstek):
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();
}
Następnie po prostu zwiększasz s.timeElapsed przy każdej iteracji pętli aktualizacji.
Jest również całkowicie podatny na implementację na GPU, uwalniając w ten sposób procesor od wykonywania jakiejkolwiek pracy. Implementacja GPU może wyglądać następująco:
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);
}
Moduł cieniujący wierzchołki GPU rekonstruowałby następnie pozycję cząstki za pomocą równania fizyki, a mundury / stałe zostałyby do niej przekazane - podobnie jak wersja procesora.
Aby dodać trochę wariancji, możesz użyć większej liczby jednoczesnych eksplozji z nieco różniącymi się parametrami, animując kolory / alfa, wybierając różne pozycje początkowe. itp.