Модель программирования Component Object Model. Разработка COM-сервера, страница 32

if (m_hRC) // Удаляем контекст

{

wglDeleteContext(m_hRC);

m_hRC = 0;

}

bHandled = TRUE;

return 0;

Введите вспомогательную функцию SetBkColor, которая будет вызвана из двух мест программы. Она изменяет цвет фона окна, а точнее, цвет стирания окна OpenGL.

void COpenGL::SetBkColor()

{

GLclampf red = GetRValue(m_BkClr)/255.f,// Расщепление цвета на три компоненты

green = GetGValue(m_BkClr)/255.f,

blue = GetBValue(m_BkClr)/255.f;

glClearColor (red, green, blue, 0.f); // Установка цвета фона (цвета стирания)

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Непосредственное стирание

}

Так как мы собираемся демонстрироавть в окне OpenGL графики функций, диапазон изменения которых нам заранее неизвестен, то следует использовать предварительное масштабирование координат точек графика. Нам надо знать габариты изображаемого объекта и для упрощения этой задачи мы введем вспомогательную глобальную функцию корректировки экстремумов.

inline void MinMax (float d, float& Min, float& Max)

{

if (d > Max)              // Одновременная коррекция минимума и максимума

Max = d;

else if (d < Min)

Min = d;

}

Функция перерисовки

Перерисовка изображения OpenGL состоит в том, что обнуляется буфер цвета и буфер глубины (буфер третьей координаты). Затем в матрицу моделирования (GL_MODELVIEW), которая уже выбрана в качестве текущей, загружается единичная матрица (glLoadIdentity). После этого происходит установка освещения, с тем, чтобы на него не действовали преобразования сдвига и вращения. Лишь после этого матрица моделирования умножается на матрицу сдвига и вращения. Чтобы рассмотреть изображение, достаточно иметь возможность вращать его вокруг двух осей (X и Y). Поэтому мы домножаем матрицу моделирования на две матрицы вращения (glRotatef). Сначала вращаем вокруг оси X, затем вокруг оси Y. Введите тело этой функции в файл реализации.

HRESULT COpenGL::OnDraw (ATL_DRAWINFO& di)

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

SetLight();    // Установка параметров освещения

glTranslatef (m_xTrans,m_yTrans,m_zTrans);// Формирование матрицы моделирования

glRotatef (m_AngleX, 1.0f, 0.0f, 0.0f );

glRotatef (m_AngleY, 0.0f, 1.0f, 0.0f );

glCallList(1);             // Вызов рисующих команд из списка

SwapBuffers(m_hdc);// Переключение буферов

return S_OK;

}

Подготовка сцены OpenGL

Далее последует ряд методов класса, которые не являются обработчиками событий (их нет в карте сообщений). Они носят вспомогательный характер, поэтому вы просто вставляете их в файл реализации.

Считая, что данные о координатах точек изображаемой поверхности уже известны и расположены в контейнере m_cPoints, напишем коды функции  DrawScene(), которая создает список команд OpenGL. Как вы помните, одним из технологических приемов OpenGL, которые ускоряют процесс передачи (rendering), является предварительная заготовка изображения, то есть запоминание и компиляция списка рисующих команд. Список ограничивается операторными скобками вида:

glNewList(1, GL_COMPILE);

//===== Здесь располагаются команды OpenGL

glEndList();

Первый параметр glNewList (типа GLuint) идентифицирует список с тем, чтобы программист мог одновременно использовать несколько списков и вызывать их в нужные моменты времени по номеру. Вызов нашего (единственного) списка мы будем производить командой glCallList(1);.

Напомним, что отображаемый график представляет собой криволинейную поверхность (например, равного уровня температуры). Ось Y, по которой откладываются интересующие пользователя значения функции, направлена вверх. Ось X направлена вправо, а ось Z — вглубь экрана. Часть плоскости (X, Z), для точек которой известны значения Y, представляет собой координатную сетку. Изображаемая поверхность расположена над плоскостью (X, Z), а точнее, над этой сеткой. Поверхность можно представить себе в виде одеяла, сшитого из множества лоскутов. Каждый лоскут мы будем задавать в виде четырехугольника, как-то ориентированного в пространстве. Все множество четырехугольников поверхности также образует сетку. Для задания последовательности четырехугольников в OpenGL существует пара команд: