Подготовка сцены
Изображение сферы целесообразно создать заранее (при вызове функции Init), а затем воздействовать на него матрицей моделирования, коэффициенты которой изменяются в соответствии с алгоритмом случайных девиаций вектора вращения. При разработке кода функции Init надо учесть специфику работы с функцией glDrawElements, которая обсуждалась выше. Кроме того, здесь мы производим установку освещенности, технологию и детали которой можно выяснить в сопровождающей документации (MSDN). Введите следующие коды функции инициализации и вставьте их до функции перерисовки. void Init() { glClearColor (0, 0, 0, 0); // Цвет фона (на сей раз традиционно черный) glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); glEnable(GL_CULL_FACE); // Включаем механизм учета ориентации полигонов glCullFace(GL_BACK); // Не учитываем обратные поверхности полигонов
float pos[] = { 0, 0, 1, 0 }; glLightfv(GL_LIGHT0, GL_POSITION, pos); // Задаем позицию источника света float amb[] = { 0.05f, 0.05f, 0.05f, 1 }; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb); // Задаем величину окружающей освещенности float dif[] = { 0.9f, 0.9f, 0.9f, 1 }; glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); // Задаем величину диффузной освещенности float spec[] = { 0.6f, 0.6f, 0.6f, 1 }; glMaterialfv(GL_FRONT, GL_SPECULAR, spec); // Задаем отражающие свойства материала glMateriali(GL_FRONT, GL_SHININESS, 40); // Задаем степень блесткости материала
//====== Настройка OpenGL на использование массивов glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
srand (time(0)); // Подготовка ГСЧ gShift = Point3D (Rand(gdShift), Rand(gdShift), Rand(gdShift));
VERT *Vert = new VERT[gnVert]; // Захват памяти под динамические массивы TRIA *Tria = new TRIA[gnTria];
Sphere (Vert, Tria); // Создание изображения
//=== Задание адресов трех массивов (вершин, нормалей и цветов), а также шага перемещения по ним glVertexPointer (3, GL_FLOAT, sizeof(VERT), &Vert->v); glNormalPointer (GL_FLOAT, sizeof(VERT), &Vert->n); glColorPointer (3, GL_UNSIGNED_BYTE, sizeof(VERT), &Vert->c);
glNewList(1, GL_COMPILE); // Формирование списка рисующих команд glDrawElements(GL_TRIANGLES, gnTria*3, GL_UNSIGNED_INT, Tria); glEndList();
delete [] Vert; delete [] Tria; // Освобождение памяти, так как список сформирован } Массив вершин, нормалей и цветов Три команды glEnableClientState говорят о том, что при формировании изображения будут заданы три массива (вершин, нормалей и цветов), а три команды вида gl*Pointer непосредственно задают адреса этих массивов. Здесь важно правильно задать не только адреса трех массивов, но и шаги перемещения по ним. Так как мы, вместо трех массивов, пользуемся одним массивом структур из трех полей, то шаг перемещения по всем трем компонентам одинаков и равен sizeof (VERT) — размеру одной переменной типа VERT. Массив вершин (Vert типа VERT*) и индексов их обхода (Tria типа TRIA*) создаются динамически внутри функции Init. Характерно, что после того, как закончилось формирование списка рисующих команд OpenGL, мы можем освободить память, занимаемую массивами, так как вся необходимая информация уже хранится в списке. Формирование массивов производится в функции Sphere, которую еще предстоит разработать. Далее по коду Init идет формирование списка рисующих команд. Так как массивы вершин и индексов их обхода при задании треугольников уже сформированы, то список рисующих команд создается с помощью одной команды glDrawElements. Ее параметры указывают: ¨ тип геометрических примитивов (GL_TRIANGLES), ¨ размер массива индексов, описывающих порядок выбора вершин (gnTria*3), ¨ тип переменных, из которых составлен массив индексов (GL_UNSIGNED_INT), ¨ адрес начала массива индексов. Команды: srand(time(0)); // Подготовка ГСЧ gShift = Point3D(Rand(gdShift), Rand(gdShift), Rand(gdShift)); позволяют задать характер вращения сферы. Константа const double gdShift =.5; выполняет роль регулятора (ограничителя) степени подвижности сферы. Если вам захочется, чтобы сфера вращалась более резво, то увеличьте эту константу и перекомпилируйте проект.
|