Требования OpenGL
В этом уроке мы продолжим разработку DLL-модуля, который после регистрации в системе в качестве СОМ-объекта позволит любому другому клиентскому приложению, обладающему свойствами контейнера объектов СОМ использовать его для отображения в контексте OpenGL трехмерного графика функции, заданной произвольным массивом чисел. Данные для графика СОМ-объект берет из файла, на который указывает пользователь клиентского приложения. Кроме этого, объект предоставляет клиенту возможность перемещения графика вдоль трех пространственных осей, вращения вокруг вертикальной и горизонтальной осей и просмотра как в обычном, так и скелетном режиме. Регулируя параметры освещения поверхности, пользователь может добиться наибольшей реалистичности изображения, то есть усилить визуальный эффект трехмерного пространства на плоском экране.
Графики могут представлять результаты расчета какого-либо физического поля, например поверхности равной температуры, давления, скорости, индукции, напряжения и т. д. в части трехмерного пространства, называемой расчетной областью. Пользователь объекта должен заранее подготовить данные и записать их в определенном формате в файл. Объект по команде пользователя считывает данные, нормирует, масштабирует и изображает в своем окне, внедренном в окно приложения-клиента. Пользователь, манипулируя мышью, управляет местоположением и вращением графика, а открыв стандартный диалог Properties, изменяет другие его атрибуты.
ATL (Active Template Library) – это библиотека шаблонов функций и классов, которая разработана с целью упрощения и ускорения разработки СОМ-объектов. Несмотря на заявления о том, что ATL не является альтернативой MFC, а лишь дополняет ее, побудительной причиной разработки этой библиотеки был тот факт, что объекты СОМ, разработанные с помощью MFC, и внедренные в HTML-документ, работали слишком медленно. Наследование от cobject и все те удобства, которые оно приносит, обходятся слишком дорого в смысле быстродействия, и в условиях web-страницы объекты MFC-происхождения проигрывают объектам, разработанным с помощью COM API. В библиотеке ATL не используется наследование от cobject и некоторые другие принципы построения классов, характерные для MFC. За счет этого удалось повысить эффективность работы СОМ-объектов и ускорить их функционирование даже в условиях web-страниц. Пользуясь справкой (Help), вы, наверное, видели, что многие оконные методы реализованы не только в классе cwnd, но и в классе cwindow. Последний является классом из иерархии библиотеки ATL, и именно он является главной фигурой при разработке окон СОМ-объектов.
Вместо тестового изображения с надписью ATL 4.0, которым мы научились кое-как управлять, поместим в окно СОМ-объекта OpenGL-изображение поверхности в трехмерном пространстве. Точнее, мы хотим дать клиенту нашего СОМ-объекта возможность пользоваться всей той функциональностью, которая была разработана в уроке 7. Вы помните, что изображение OpenGL может быть создано в окне, которое прошло специальную процедуру подготовки. Необходимо создать и сделать текущим контекст передачи OpenGL (HGRC). Вы также помните, что подготовку контекста надо рассматривать как некий обязательный ритуал, в котором порядок действий определен. Повторим его:
- установка стиля окна;
- обработка сообщения WM_ERASEBACKGROUND и отказ от стирания фона;
- установка pixel-формата;
- создание контекста устройства (нос) и контекста передачи (HGLRC);
- специфическая обработка сообщения WM_SIZE;
- обработка сообщения WM_PAINT;
- освобождение контекстов при закрытии окна.
Чтобы использовать функции библиотеки OpenGL, надо подключить их к проекту. На этапе компоновки они будут интегрированы в коды СОМ-сервера.
- В окне Solution Explorer поставьте фокус на строку с именем проекта ATLGL и нажмите кнопку Properties, которая расположена на панели инструментов этого окна.
- В левом окне диалога ATLGL Property Pages найдите и выберите ветвь дерева Linker.
- В раскрывшемся поддереве выберите ветвь Input и перейдите в строку Additional Inputs в таблице правого окна.
- Поставьте фокус во вторую колонку этой строки и в конец существующего текста ячейки добавьте, не стирая содержимое ячейки, имена подключаемых библиотек OPENGL32.LIB GLU32.LIB, не забыв о разделяющих пробелах. Нажмите ОК.
- В конец файла библиотечных заголовков stdafx.h добавьте строки:
#include <math.h> #include <gl/gl.h> # include <gl/glu.h>
При работе с трехмерными координатами мы пользовались вспомогательным классом CPoint3D, который здесь нам тоже понадобится. Нужны будут и все переменные, которые были использованы ранее для управления сценой OpenGL. Там, если вы помните, был контейнер STL типа vector для хранения точек изображения. Использование контейнеров требует подключения соответствующих файлов заголовков, поэтому вставьте в конец файла stdafx.h следующие строки:
#include <vector> using namespace std;
Так как мы собираемся демонстрировать в окне OpenGL графики функций, диапазон изменения которых нам заранее не известен, то следует использовать предварительное масштабирование координат точек графика. Нам надо знать габариты изображаемого объекта и для упрощения этой задачи введем вспомогательную глобальную функцию корректировки экстремумов:
inline void MinMax (float d, floats Min, floats Max) { if (d > Max) Max = d; else if (d < Min) Min = d; }
Описатель inline сообщает компилятору, что функцию можно не реализовывать в виде отдельной процедуры, а ее тело желательно вставлять в точки вызова, с тем чтобы убрать код обращения к стеку. Окончательное решение при этом остается за компилятором.