Макет консольного приложения, использующего библиотеку GLAUX
В отличие от обычной консольной программы Win32, в проект программы, использующей OpenGL, надо добавить три файла с расширениями .lib из каталога DEVSTUDIO\VC\LIB: opengl32.lib, glu32.lib и glaux.lib. В этих файлах содержатся данные, с помощью которых компоновщик организует в исполняемом файле программы вызовы функций OpenGL из динамических библиотек opengl32.dll и glu32.dll (они расположены в каталоге WINDOWS\SYSTEM). Показанная ниже программа 1.1 выполняет анимацию сферы, которая движется в экранном окне в направлении "слева направо". Генерация изображения трехмерной сцены выполняется в функции display(). Консольные приложения, которые будут рассматриваться в данной лекции, имеют похожую структуру и различаются содержанием функции display().
#include <windows.h> // Заголовочный файл с описаниями функций Windows #include <GL/gl.h> // Заголовочные файлы библиотеки OpenGL #include <GL/glu.h> #include <GL/glaux.h>
// Прототипы функций обратной связи (для автоматического вызова из GLAUX) void CALLBACK resize(int width, int height); void CALLBACK display(void);
void main() { // Параметры обсчета сцены в OpenGL: цветовой режим RGBA, удаление // невидимых поверхностей и линий, двойная буферизация auxInitDisplayMode(AUX_RGBA | AUX_DEPTH | AUX_DOUBLE);
// Создание окна OpenGL с заголовком "Программа 1.1" // Размер окна – 400х400 пикселей. Левый верхний угол окна // задается экранными координатами (50, 10). auxInitPosition(50, 10, 400, 400); auxInitWindow("Программа 1.1");
// В случае, когда окно не получает сообщений от клавиатуры, мыши или // таймера, то будет вызываться функция display. Так можно получить // анимацию. Если анимация не нужна, то эта строка лишняя. auxIdleFunc(display);
// Задание функции, которая будет вызываться при изменении // размеров окна Windows. auxReshapeFunc(resize);
// Включение ряда параметров OpenGL glEnable(GL_ALPHA_TEST); // Учет прозрачности glEnable(GL_DEPTH_TEST); // Удаление невидимых поверхностей glEnable(GL_COLOR_MATERIAL); // Синхронное задание цвета рисования // и цвета материала объектов glEnable(GL_BLEND); // Разрешение смешения цветов glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LIGHTING); // Учет освещения glEnable(GL_LIGHT0); // Включение нулевого источника света
// Задание положения и направления нулевого источника света float pos[4] = { 3, 3, 3, 1 }; float dir[3] = { -1, -1, -1 }; glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir);
// Задание функции отрисовки окна. Эта функция будет вызываться всякий // раз, когда потребуется перерисовать окно на экране (например, когда // окно будет развернуто на весь экран) auxMainLoop(display); }
void CALLBACK resize(int width, int height) { // Указание части окна для вывода кадра OpenGL glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity();
// Задание типа проекции (glOrtho - параллельная, glFrustum - // перспективная). Параметры функций определяют видимый объем // (левая стенка - пять единиц влево, правая - пять единиц вправо, // далее задаются нижняя стенка, верхняя, передняя и задняя) glOrtho(-5, 5, -5, 5, 2, 12);
// Задание позиции наблюдателя (0, 0, 5), направление луча // зрения (на точку (0, 0, 0)), вектор, принимаемый за направление // "вверх" (0, 1, 0) (т.е. параллельно оси Y). gluLookAt(0,0,5, 0,0,0, 0,1,0); glMatrixMode(GL_MODELVIEW); }
void CALLBACK display(void) { // Очистка буфера кадра glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Перенос системы координат, связанной с объектом, на 0.01 glTranslated(0.01, 0, 0); // Рисование в начале координат, связанных с объектом, сферы // радиусом 1, окрашенной в красный цвет glColor3d(1, 0, 0); auxSolidSphere(1);
// Копирование содержимого буфера кадра на экран auxSwapBuffers(); } Программа 1.1 Имена функций OpenGL Рисование сферы в программе 1.1 выполняется при помощи двух функций: glColor3d(1, 0, 0); auxSolidSphere(1); Функция glColor3d() устанавливает текущий цвет, а auxSolidSphere() рисует сферу единичного радиуса с центром в начале координат.
Цвет в режиме RGBA (режим был задан в функции main()) задается четырьмя числами в диапазоне от 0 до 1: красная компонента, синяя, зеленая и прозрачность. В программе 1.1 прозрачность не нужна, поэтому вызывается вариант функции glColor() с тремя параметрами. Значение четвертого параметра, прозрачности, по умолчанию равно единице (1 – абсолютно непрозрачный материал, 0 – абсолютно прозрачный). OpenGL была разработана для языка Си, а не Си++, поэтому вместо перегруженных полиморфных функций в этой библиотеке реализованы наборы функций с похожими именами, в которых условно обозначено количество параметров функции. Имена полиморфных функций OpenGL выбраны согласно следующему правилу: Имя функции[n=число параметров][тип параметров] Тип параметров обозначается одной из английских букв: 'b' – байт со знаком (char или GLbyte) 's' – короткое целое (short или GLshort) 'i' – целое (int или GLint) 'f' – вещественное (float или GLfloat) 'd' – вещественное с двойной точностью (double или GLdouble) 'ub' – беззнаковый байт (unsigned char или GLubyte) 'us' – беззнаковое короткое целое (unsigned short или GLushort) 'ui' – беззнаковое целое (unsigned int или GLuint) 'v' – массив из n параметров указанного типа Имя glColor3d() означает, что у функции есть три параметра типа double. Например, есть еще функция glColor3i() с тремя параметрами типа int. Для целочисленных типов значение цветовой компоненты приводится к диапазону [0, 1] путем деления переданного значения на максимальное значение данного типа. Ниже приведены три поясняющих примера:
double array[] = {0.5, 0.75, 0.3, 0.7}; glColor3dv(array); // Цвет задается массивом типа double glColor3ub(200, 100, 0); // Преобразование 200/256,100/256,0/256 glColor3d(0.25, 0.25, 0); // темно-желтый glColor3ub(0, 100, 0); // темно-зеленый glColor3ub(0, 0, 255); // ярко-синий
Системы координат В OpenGL используются три системы координат: левосторонняя, правосторонняя и оконная. Первые две системы являются трехмерными и отличаются друг от друга направлением оси z: в правосторонней она направлена на наблюдателя, а в левосторонней – от наблюдателя внутрь экрана. В большинстве случаев используется правосторонняя (мировая) система координат. Левосторонняя система применяется только для задания параметров проекционного преобразования. Отображение проекции трехмерной сцены производится в двумерной оконной системе координат, связанной с окном на экране.
Смысл преобразований трехмерных координат, необходимых для получения на экране двумерного изображения трехмерной сцены, можно пояснить с помощью аналогии между OpenGL и фотоаппаратом (рис. 1.2). В обоих случаях для получения изображения выполняются следующие шаги: 1) установка штатива и наведение фотоаппарата (видовое преобразование); 2) размещение фотографируемых объектов (модельное преобразование); 3) выбор объектива и/или настройка увеличения (проекционное преобр.); 4) выбор размера печатаемой фотографии (оконное преобразование). Рис. 1.2. Аналогия между фотоаппаратом и OpenGL.
Рис. 1.3. Порядок выполнения преобразований координат вершины объекта.
В программах на OpenGL видовые преобразования следует задавать ранее модельных. Проекционное и оконное преобразования можно описывать в любом месте программы до рисования объектов. В целом, порядок задания параметров преобразований может отличаться от строго определенного порядка выполнения математических операций над трехмерными координатами для получения двумерных экранных координат (рис. 1.3).
Матрицы преобразований В OpenGL различные преобразования объектов сцены описываются с помощью матриц размера 4x4. Есть три типа матриц: видовая, проекционная и текстурная. Видовая матрица описывает преобразования объекта в мировых координатах: параллельный перенос, масштабирование и поворот. Проекционная матрица задает вид проекции трехмерных объектов на плоскость экрана (в оконные координаты), а текстурная матрица управляет наложением текстуры на объект. Перед вызовом функций, изменяющих матрицу определенного типа, сначала необходимо установить эту матрицу в качестве текущей с помощью функции: void glMatrixMode(GLenum mode) Параметр mode принимает значения GL_MODELVIEW, GL_PROJECTION или GL_TEXTURE. Значения элементов текущей матрицы можно задать в явном виде функцией: void glLoadMatrix[f d](GLtype* m) где m указывает на 16-ти элементный массив типа float или double. В нем сначала хранится первый столбец матрицы, затем второй, третий и четвертый.
Функция void glLoadIdentity(void) заменяет текущую матрицу на единичную. Содержимое текущей матрицы часто бывает нужно сохранить для дальнейшего использования. Для этого применяются функции сохранения/восстановления матрицы из служебного стека OpenGL: void glPushMatrix(void) void glPopMatrix(void) Для матриц каждого типа в OpenGL есть отдельный стек. Для видовых матриц его глубина равна, как минимум, 32, для двух других типов матриц – минимум 2. Для умножения текущей матрицы на другую матрицу справа используется функция: void glMultMatrix[f d](GLtype* m) где m является указателем на матрицу размером 4x4. Однако чаще для изменения матриц в OpenGL удобно пользоваться специальными функциями, которые по значениям параметров преобразований создают нужную матрицу и перемножают ее с текущей. Чтобы сделать текущей созданную матрицу, надо перед вызовом этих функций вызывать glLoadIdentity(). Теперь кратко рассмотрим преобразования, применяемые для отображения трехмерных объектов сцены в окно приложения (рис. 1.3).
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|