Пример выполнения модельных преобразований
Параллельный перенос Преобразование переноса рассмотрим на примере рисования сферы. Вызов auxSolidSphere(0.5); приводит к рисованию сферы радиусом 0.5 с центром в начале видовых координат, которое по умолчанию совпадает с началом мировой системы координат. Чтобы расположить центр сферы в точке (x 0, y 0, z 0), надо переместить начало координат в эту точку, т.е. надо перейти к новым координатам. При программировании графики и анимации эта процедура выполняется очень часто. В ряде случаев после смещения и/или поворота видовой системы координат расчет координат вершин объекта сильно упрощается. Для переноса системы координат на вектор (dx, dy, dz) есть функция: void glTranslated(double dx, double dy, double dz) Применение этой функции демонстрируется в программе 1.2 (по сравнению с программой-макетом 1.1 в этой программе реализована другая функция рисования трехмерной сцены, состоящей из 3 сфер разного радиуса с центрами в разных точках).
void CALLBACK display(void) { // Очистка буфера кадра glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix(); // Сохранение текущей видовой матрицы
glTranslated(1.4, 0, 0); // Перенос вдоль оси Х на 1.4 glColor3d(0, 1, 0); // Зеленый цвет auxSolidSphere(0.5); // Рисование сферы с центром в (1.4, 0, 0) // в мировой системе координат glTranslated(1, 0, 0); // Перенос вдоль оси Х на 1.0 glColor3d(0, 0, 1); // Синий цвет auxSolidSphere(0.3); // Рисование сферы с центром в (2.4, 0, 0)
glPopMatrix(); // Восстановление сохраненной видовой // матрицы (т.е. возврат к старой видовой // системе координат)
glColor3d(1, 0, 0); // Красный цвет auxSolidSphere(0.75); // Рисование сферы с центром в (0, 0, 0) // в мировой системе координат
// Копирование содержимого буфера кадра на экран auxSwapBuffers(); } Фрагмент программы 1.2
Поворот
Поворот видовой системы координат выполняет функция: void glRotated(double angle, double x0, double y0, double z0) Эта функция поворачивает систему координат на угол angle (в градусах) против часовой стрелки вокруг вектора (x 0, y 0, z 0). Применение этой функции показано в программе 1.3.
void CALLBACK display(void) { // Очистка буфера кадра glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3d(1, 0, 0); auxSolidCone(1, 2); // Конус с центром основания в начале // координат. Радиус основания – 1, // высота конуса – 2, ось симметрии совпа- // дает с положительным направлением оси Z glPushMatrix(); // Cохранение текущей системы координат glTranslated(1, 0, 0); // Перенос начала координат в точку (1,0,0) glRotated(75, 1, 0, 0); // Поворот системы координат на 75 градусов // вокруг оси X. glColor3d(0, 1, 0); auxSolidCone(1, 2); // Еще один конус glPopMatrix(); // Возврат к сохраненной системе координат
// Копирование содержимого буфера кадра на экран auxSwapBuffers(); } Фрагмент программы 1.3
Выполнив программу 1.3, можно убедиться, что в мировой системе координат конус оказался повернут. Итак, чтобы нарисовать объект не в начале координат, надо: 1) сохранить текущую систему координат; 2) выполнить сдвиг (glTranslated()) и/или поворот (glRotated()); 3) нарисовать требуемые объекты; 4) вернуться к старой системе координат. Вызовы glPushMatrix()/glPopMatrix() могут быть вложенными. Обычно в исходном тексте пары этих функций выделяются отступами, например:
glPushMatrix(); ... glPushMatrix(); ... glPopMatrix(); ... glPopMatrix();
Количество вызовов glPopMatrix() должно соответствовать количеству вызовов glPushMatrix(), иначе будет получено неправильное изображение сцены. Максимально допустимая глубина вложенности glPushMatrix()/glPopMatrix() в OpenGL не меньше 32.
Сводка результатов Описаны основные возможности OpenGL. Приведен макет консольного приложения, использующего OpenGL и вспомогательную библиотеку GLAUX. В этом макете есть функции обратной связи (CALLBACK-функции), которые библиотека GLAUX вызывает для рисования трехмерной сцены, для реакции на изменение размеров окна и некоторые другие события. Имена функций OpenGL подчиняются правилу, согласно которому в именах функций указывается тип параметров.
В OpenGL трехмерные координаты вершин рисуемых объектов подвергаются набору преобразований, в результате которых вычисляются двумерные координаты точек в экранном окне. Смысл преобразований можно пояснить с помощью аналогии между OpenGL и фотоаппаратом. Преобразования координат задаются с помощью матриц 4x4. В лекции приведен пример выполнения модельных преобразований переноса и поворота.
Упражнения Упражнение 1 Создайте проект, состоящий из файла с исходным текстом программы 1.1 и библиотечных файлов OpenGL (opengl32.lib, glu32.lib и glaux.lib). Скомпилируйте и запустите программу. Попробуйте изменить цвет сферы, пользуясь примерами функции glColor3..() из п. 4.
Упражнение 2 С помощью перечисленных ниже функций нарисуйте стандартные фигуры библиотеки GLAUX: куб, параллелепипед и др. Значения параметров функций выбирайте в диапазоне 0.5-1.7 (фигура слишком большого размера будет выходить за пределы видимого объема).
В таблице приведены имена функций для рисования сплошных фигур. В GLAUX есть также аналогичные функции (вместо Solid имена этих функций содержат слово Wire) для рисования каркасных фигур. Например, для рисования каркаса куба надо вызвать функцию: auxWireCube(1);
Упражнение 3 С помощью функций, перечисленных в упр.2, нарисуйте стандартные фигуры библиотеки GLAUX в четыре столбца (по 5 фигур в каждом столбце): в 1-м и 3-м столбцах слева сплошные фигуры, во 2-м и 4-м – каркасные.
Упражнение 4 Изобразите оси координат и радиус-вектор точки (3, 3, 3). Для рисования отрезков используйте цилиндры малого диаметра, для рисования стрелок – конусы. Ось X покажите красным цветом, ось Y – зеленым, ось Z – синим. В начало координат и в точку (3,3,3) поместите сферу небольшого радиуса.
Рисование осей координат оформите в виде отдельной функции. Ее можно будет использовать в других программах на OpenGL в отладочных целях (например, можно нарисовать оси и посмотреть расположение объектов сцены относительно координатных осей). Примечание: функция auxSolidCylinder() рисует цилиндр, ориентированный по отрицательному направлению оси Y видовой системы координат, причем центр нижнего основания цилиндра располагается в точке (0, 0, 1).
Упражнение 5 Нарисуйте каркасный параллелепипед, у которого длины сторон, параллельных координатным осям X, Y, Z, находятся в отношении 1:1:10. Задайте такие параметры функции glOrtho(), чтобы параллелепипед целиком попадал в видимый объем. Убедитесь, что стороны, параллельные оси Z, в проекции на экране остаются параллельными. Чтобы не подбирать параметры освещения, в данном случае можно отключить моделирование направленного освещения и установить максимальную интенсивность рассеянного освещения. Для этого удалите из своей программы функции включения нулевого источника света и функции настройки его параметров: 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); Вместо этих функций включите функцию, задающую максимальную интенсивность рассеянного освещения: float ambient[4] = { 1.0, 1.0, 1.0, 1 }; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); Смените тип проекции с ортографической на перспективную (glFrustum()). Регулируя угол раскрытия видимого объема, добейтесь, чтобы параллелепипед попадал в него целиком. Убедитесь, что параллельность сторон параллелепипеда вдоль оси Z при перспективной проекции не сохраняется.
Упражнение 6 С помощью функций glTranslate() и glRotate() нарисуйте снеговика (туловище – три сферы разного радиуса, руки – сферы, шапка – конус, нос – тоже конус, глаза – сферы, рот – параллелепипед).
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|