Листинг 13.4. Программа на языке С для рисования частиц как точек
void drawPoints()
{
glPointSize(2.0):
glVertexPointer(3, GL_FL0AT, 0, verts): .
продолжение тУ
Листинг 13.4 (продолжение)
glColorPointer (3. GL_FL0AT. 0, colors): gl Vertex^ftribPointerARB(VELOCITY_ARRAY, 3, GLJLOAT.
GL_FALSE. 0. velocities): glVertexAttribPointerARB(START_TIME_ARRAY. 1, GLJLOAT.
GLJALSE, 0. startTimes):
glEnableClientState(GL_VERTEX_ARRAY); glEnableCli entState(GL_COLOR_ARRAY); glEnableVertexAttribArrayARB(VELOCITY_ARRAY): gl EnableVertexAttribArrayARB(START_TIME_ARRAY):
glOrawArrays(GL_POINTS. 0. arrayWidth * arrayHeight);
glDisableClientState(GL_VERTEX_ARRAY): glOi sableCl ientState(GL_COLOR_ARRAY): glDi sableVertexAttri bArrayARB(VELOCITY_ARRAY): glDisableVertexAttribArrayARB(START_TIME_ARRAY):
}
Чтобы получить эффект анимации, приложение должно передавать свое значение времени вершинному шейдеру (листинг 13.5). Переменная Ра rticleTi me увеличивается на единицу при смене кадров, и это значение заносится в uniform-переменную Time. Это позволяет вершинному шейдеру учитывать значение времени в вычислениях.
Листинг 13.5. Фрагмент кода на языке С для обновления переменной с новым кадром
if (DoingParticles)
{
location = glGetUniformLocationARB(ProgramObject. "Time"):
ParticleTime += O.OOlf; glllmformlfARB(location, ParticleTime):
CheckOglErrorO:
}
13.6.2. Вершинный шейдер хлопушки с конфетти
Вершинный шейдер (листинг 13.6) выполняет основную работу в примере рендеринга методом создания систем частиц. Вместо того чтобы просто преобразовать входные вершинные координаты, шейдер считает эти координаты начальными для вычисления новых координат с учетом значения uniform-переменной Time. И уже эти новые координаты будут преобразовываться и передаваться для рендеринга.
В вершинном шейдере определены attribute-переменные Velocity и StartTime (определение массивов дополнительных атрибутов вершин и связывание их с соответствующими переменными шейдера описано в предыдущем разделе). Поэтому у шейдера всегда будут обновленные значения переменных Vel oci ty, StartTime, а также стандартных вершинных атрибутов gl_Vertex и gl_Col or.
Вершинный шейдер сначала вычисляет время жизни частицы. Если это значение меньше нуля, частица еще не создана, и тогда ей просто присваивается цвет фона через uniform-переменную Background. (Можно показать еще не «родившиеся» частицы, присвоив им их собственный цвет. Можно также передавать значе ние t во фрагментный шейдер как varying-переменную, чтобы затем отбрасывать фрагменты с t меньшим 0. Но здесь этого делать не обязательно.)
Осталось преобразовать координаты и сохранить результат gl_Position.
Листинг 13.6. Вершинный шейдер хлопушки с конфетти, использующий метод систем частиц
uniform float Time; // обновляется приложением с каждым кадром
uniform vec4 Background; // постоянный цвет фона
attribute vec3 Velocity; // начальная скорость
attribute float StartTime: // время активации частицы