Конструктор класса GRIDBALL создает двумерную сетку вершин на основе полученных радиуса шара, его цвета, шага сетки по широте и долготе, как это показано в листинге 22.18.
Листинг 22.18
GRIDBALL::GRIDBALL(ColorFon F.double R_z.double Мег.double Par ): Fon(F),Rz(R_z).L0NG_GR(Me r).LAT_GR(Par)
{
double L0NG_ST - L0NG_GR*Pi/180.Ol; //Шаг меридианов и параллелей
double LAT_ST - LAT_GR*Pi/180.01: //в радианах.
N1 - int((2*Pi+0.0001)/LONG_ST+l); //Количество меридианов.
Nh - int((Pi+0.0001)/LAT_ST+l); //Количество параллелей.
double di.dj; //Долгота di и широта dj текущей вершины.
int i.j: //Индексы текущей вершины
Grid - new pMERIDIAN[Nl]; //Создание массива указателей строк матрицы. for(i - 0.di - -Pi+LONG_ST/2.0;i<Nl;di+ - L0NG_ST.i++) //Цикл по меридианам. {
Grid[i] - new TEXVERTEXl[Nh]; //Создание строки матрицы - массива точек for(j «= O.dj - -Pi/2;j<Nh;dj+ - LAT_ST.j++)//пересечения меридиана с параллелью {
SetKnot(i. j.di. dj); //Вычисление декартовых координат текущего узла.
Grid[i][j].R - Fon.R;
Grid[i][j].G - Fon.G:
Grid[i][j].B - Fon.B;
}
}
}
Деструктор класса, чей код приведен в листинге 22.19, освобождает память от сетки при уничтожении объекта.
Листинг 22.19
GRIDBALL::~GRIDBALL() {
if(Grid)
{for(int i - 0;i<Nl:i++)
Материал и освещение
if(Grid[i])
{delete Grid[i]:Grid[i] - 0;} delete Grid: Grid - 0: }
}
Деструктор проверяет поле Grid на равенство нулю, а после освобождения памяти очищает это поле, несмотря на то что объект уничтожается, а вместе с ним исчезнет и поле Grid. В данном проекте не может возникать ситуация, когда при вызове деструктора поле Gri d не было бы заполнено указателем на сетку вершин. Сетка создается в конструкторе, уничтожить ее может только деструктор, а после его вызова объекта уже нет. Но, повторимся, практика показывает, что в реальных проектах такая проверка лишней не бывает. Например, при сопровождении системы в класс могут добавить методы DestroyGrid( ) и CreateGrid( ) и забыть откорректировать деструктор.
Теперь следует рассмотреть методы класса GLOBE. Рисование сетки и шара выполняется одной функцией, которая получает указатель на сетку Gr и признак вывода сетки в виде поверхности или каркасной модели Fill. Характер книги, предназначенной для знакомства с принципами формирования изображений средствами API Windows, не позволяет излагать материал с полнотой справочника. Поэтому в дополнение к изложенным ранее сведениям о примитивах OpenGL следует отметить, что при выводе линий программист может задавать их толщину при помощи функции gl Li neWidth( ), а указание конвейеру рассматривать приведенные вершины как последовательность узлов одной ломаной, которые задается константой GL_L INE_STRIР, как это показано в листинге 22.20.