Там действительно нет необходимости хранить память для каждой частицы и анимировать каждую частицу в отдельности. Вы можете сделать это процедурно, восстанавливая положение частицы во время рисования, используя классическое физическое уравнение. s = ut + 1 / 2.at ^ 2
Простой пример (без постоянного ускорения частиц):
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();
}
Затем вы просто увеличиваете s.timeElapsed на каждой итерации цикла обновления.
Он также полностью поддается реализации на GPU, освобождая ваш процессор от необходимости выполнять какую-либо работу. Реализация gpu может выглядеть так:
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);
}
Вершинный шейдер GPU затем восстанавливал бы положение частицы с помощью уравнения физики и передавал ему униформы / константы - так же, как это делала версия CPU.
Чтобы добавить некоторую дисперсию, вы можете использовать больше одновременных взрывов с немного отличающимися параметрами, анимируя цвета / альфа, выбирая разные начальные позиции. и т.п.