Листинг 13.3. Программа на языке С для создания начальных данных частиц
static GLint arrayWidth. arrayHeight; static GLfloat *verts = NULL; static GLfloat *colors = NULL: static GLfloat Velocities = NULL; static GLfloat *startTimes = NULL;
void createPoints(GLint w, GLint h)
{
GLfloat *vptr, *cptr. *velptr, *stptr;
GLfloat i. j ;
if (verts != NULL) free(verts):
verts = malloc(w * h * 3 * sizeof(float)): colors = malloctw * h * 3 * sizeof(float)): velocities = malloc(w * h * 3 * sizeof(float)); startTimes = malloc(w * h * sizeof(float)):
vptr = verts; cptr = colors; velptr = velocities: stptr = startTimes:
for (i =0.5 /w- 0.5: i < 0.5: i = i + 1.0/w) for (j = 0.5 / h - 0.5: j < 0.5; j = j + 1.0/h)
{
*vptr = i:
*(vptr + 1) = 0.0;
*(vptr + 2) = j:
vptr += 3;
*cptr = ((float) randO / RAND_HAX) * 0.5 + 0.5:
*(cptr + 1) = ((float) randO / RAND_MAX) * 0.5 + 0.5:
*(cptr + 2) = ((float) randO / RAND_MAX) * 0.5 + 0.5;
cptr += 3:
*velptr = (((float) randO / RAND_MAX)) + 3.0;
*(velptr + 1) = ((float) randO / RAND_MAX) * 10.0:
*(velptr + 2) = (((float) randO / RAND_MAX)) + 3.0:
velptr += 3;
*stptr = ((float) randO / RAND_MAX) * 10.0: stptr++:
}
arrayWidth = w;
arrayHeight = h:
}
У OpenGL есть встроенные атрибуты координат и цвета вершины, которые и будут использоваться для передачи координат и цвета частицы. Начальную скорость и начальное время придется передавать через дополнительные атрибуты. Определим необходимые для этого константы:
Idefine VELOCITY_ARRAY 3
Idefine START_TIME_ARRAY 4
После создания программного объекта необходимо связать индексы дополнительных атрибутов с соответствующими именами переменных. (Это можно сделать даже до того, как вершинный шейдер связывается с программным объектом.) Все эти связи будут проверены и вступят в силу во время вызова функции glLink-ProgramARB. Чтобы связать индекс дополнительного атрибута с переменной вершинного шейдера, сделаем следующее:
glBindAttribLocat1onARB(ProgramObject. VELOCITY_ARRAY. "Velocity"):
glBindAttribLocationARB(ProgramObject, START_TIME_ARRAY, "StartTime"); После того как шейдеры скомпилированы, связаны с программным объектом и скомпонованы, можно рисовать систему частиц. Все, что для этого нужно сделать, - вызвать функцию drawPoi nts, приведенную в листинге 13.4. В этой функции размер точки устанавливается в 2, чтобы выполнять рендеринг немного больших точек. Следующие четыре строки кода устанавливают указатели на используемые массивы вершин. В данном шейдере используются четыре массива: для координат вершин (начальные координаты частиц), для цвета частиц, для начальной скорости и начального времени (времени рождения) частиц. После этого вызываются функции gl EnaЫ еС1 i entState для стандартных атрибутов вершин и gl Enabl е-VertexAttribArrayARB - для дополнительных атрибутов вершин, чтобы массивы стали доступными. Потом вызывается функция glDrawArrays для рендеринга точек, и, наконец, доступ к массивам закрывается.