Создание сферы
void Sphere(VERT *v, TRIA* t) { //====== Формирование массива вершин //====== Северный полюс v[0].v = CPointSD (0, gRad, 0); v[0].n = CPoint3D (0, 1, 0); v[0].с = gClr2; //====== Индекс последней вершины (на южном полюсе) UINT last = gnVert – 1; //====== Южный полюс v[last].v = CPointSD (0, – gRad, 0); v[last].n = CPointSD (0, – 1, 0); v[last].c = gnVert & 1? gClr2: gClrl; //====== Подготовка констант double da = PI / (gnRings +2.), db = 2. * PI / gnSects, af = PI – da/2.; bf = 2. * PI – db/2.; //=== Индекс вершины, следующей за северным полюсом UINT n = 1; //=== Цикл по широтам for (double a = da; a < af; a += da) { //=== Координата у постоянна для всего кольца double у = gRad * cos(a), //====== Вспомогательная точка xz = gRad * sin(a); //====== Цикл по секциям (долгота) for (double b = 0.; b < bf; n++, b += db) } // Координаты проекции в экваториальной плоскости double х = xz * sin(b), z = xz * cos(b); //====== Вершина, нормаль и цвет v[n].v = CPointSD (x, у, z); v[n].n = CPointSD (x / gRad, у / gRad, z / gRad); v[n].c = n & 1? gClrl: gClr2; } } //====== Формирование массива индексов //====== Треугольники вблизи полюсов for (n = 0; n < gnSects; n++) { //====== Индекс общей вершины (северный полюс) t[n].11 = 0; //====== Индекс текущей вершины t[n].12 = n + 1; //====== Замыкание t[n].13 = n == gnSects – 1? 1: n + 2; //====== Индекс общей вершины (южный полюс) t [gnTria-gnSects+n].11 = gnVert – 1; t tgnTria-gnSects+n]. 12 = gnVert – 2 – n; t [gnTria-gnSects+n].13 = gnVert – 2 t ((1 + n) % gnSects); } //====== Треугольники разбиения колец //====== Вершина, следующая за полюсом int k = 1; //====== gnSects – номер следующего треугольника S' n = gnSects; for (UINT i = 0; i < gnRings; i++, k += gnSects) { for (UINT j = 0; j < gnSects; j++, n += 2) { //======= Индекс общей вершины t[n].11 = k + j; //======= Индекс текущей вершины t[n].12 = k + gnSects + j; //======= Замыкание t[n].13 = k + gnSects + ((j + 1) % gnSects) //======= To же для второго треугольника t[n + 1].11 = t[n].11; t[n + 1].12 = t[n].13; t[n + 1].13 = k + ((j + 1) % gnSects);
Для завершения работы осталось дополнить программу стандартным набором процедур, алгоритм функционирования которых вы уже изучили:
void_stdcall OnSize(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); } void main () { auxInitDisplayMode(AUX_RGB | AUX_DOUBLE); auxInitPositiondO, 10, 512, 512); auxInitwindow("Vertex Array"); Init(); auxReshapeFunc (OnSize); auxIdleFunc (OnDraw); auxMainLoop (OnDraw); }
Запустите проект на выполнение и уберите возможные неполадки. Исследуйте функционирование программы, вводя различные значения глобальных параметров (регулировок). Попробуйте задать нечетное число секций. Объясните результат. В качестве упражнения введите возможность интерактивного управления степенью дискретизации сферы и исследуйте эффективность работы конвейера при ее увеличении.