Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Пример выполнения модельных преобразований




Параллельный перенос

Преобразование переноса рассмотрим на примере рисования сферы. Вызов

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
куб auxSolidCube(width)
параллелепипед auxSolidBox(width, height, depth)
тор auxSolidTorus(r, R)
цилиндр auxSolidCylinder(r, height)
конус auxSolidCone(r, height)
икосаэдр auxSolidIcosahedron(width)
октаэдр auxSolidOctahedron(width)
тетраэдр auxSolidTetrahedron(width)
додекаэдр auxSolidDodecahedron(width)
чайник auxSolidTeapot(width)

 

В таблице приведены имена функций для рисования сплошных фигур. В 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 Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...