Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 300065.doc
Скачиваний:
5
Добавлен:
30.04.2022
Размер:
280.06 Кб
Скачать

3. Содержание и порядок выполнения работы

  1. Создать MDI-приложение (четные варианты) или SDI-приложение (нечетные варианты) по аналогии с примерами из каталогов \ ex02 и \ex03. В каждом дочернем окне должен быть выведен с помощью линий номер варианта задания в следующим формате:

V.XX,

где XX – номер варианта (01, 02,…,33).

Замечание. При выводе линий использовать функцию glLineStipple со случайными параметрами.

  1. Откомментировать используемые в программе функции OpenGL.

  2. Оформить отчет.

Задания

Создать программу, которая рисует:

  1. Фиолетовый треугольник внутри зеленой окружности;

  2. Зеленый ромб внутри розовой окружности;

  3. Розовый квадрат на синей окружности;

  4. Черный квадрат внутри красного треугольника;

  5. Синий квадрат внутри серого ромба;

  6. Серая окружность в квадрате зеленого цвета;

  7. Коричневый ромб внутри желтого треугольника;

  8. Черный ромб внутри розового квадрата;

  9. Фиолетовая окружность внутри желтого ромба;

  10. Серая окружность внутри треугольника желтого цвета;

  11. Коричневый ромб внутри желтого треугольника;

  12. Желтый квадрат внутри зеленого треугольника;

Лабораторная работа №6 построение трехмерных изображений

В OPENGL

1. Цель работы

Овладение навыками построения трехмерных изображений в OPENGL

2. Комментарии по выполнению работы

В OpenGL левый нижний угол области вывода имеет координаты [-1; -1], правый верхний - [1, 1].

Если говорить о трехмерном пространстве, то можно сказать, что объем сцены ограничен кубом с координатами точек вершин по диагоналям (-1, -1, -1) и (1, 1, 1).

Построение куба в OpenGL сводится к построению шести квадратов, отдельно для каждой стороны фигуры (см. пример \Ex1):

glBegin (GL_QUADS); glVertex3f (1. 0, 1. 0, 1. 0); glVertex3f (-1. 0, 1. 0, 1. 0); glVertex3f (-1. 0, -1. 0, 1. 0); glVertex3f (1. 0, -1. 0, 1. 0); glEnd; glBegin (GL_QUADS); glVertex3f (1. 0, 1. 0, -1. 0); glVertex3f (1. 0, -1. 0, -1. 0); glVertex3f (-1. 0, -1. 0, -1. 0), glVertex3f (-1. 0, 1. 0, -1. 0); glEnd; glBegin (GL_QUADS); glVertex3f (-1. 0, 1. 0, -1. 0); glVertex3f (-1. 0, 1. 0, -1. 0); glVertex3f (-1. 0, -1. 0, 1. 0); glVertex3f (-1. 0, -1.0, 1.0); glEnd; glBegin (GL_QUADS); glVertex3f (1. 0, 1. 0, 1. 0); glVertex3f (1. 0, -1. 0, 1. 0); glVertex3f (1. 0, -1. 0, -1. 0); glVertex3f (1. 0, 1. 0, -1. 0); glEnd; glBegin (GL_QUADS); glVertex3f (-1. 0, 1. 0, -1. 0); glVertex3f (-1. 0, 1. 0, 1. 0); glVertex3f (1. 0, 1. 0, 1. 0); glVertex3f (1. 0, 1. 0, -1. 0); glEnd; glBegin(GL_QUADS); glVertex3f (-1. 0, -1. 0, -1. 0); glVertex3f (1. 0, -1. 0, -1. 0); glVertex3f (1. 0, -1. 0, 1. 0); glVertex3f (-1. 0, -1. 0, 1. 0); glEnd;

Чтобы выводить только ребра куба, после установления контекста воспроизведения задаем нужный режим воспроизведения полигонов:

glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);

Для некоторых базовых фигур существует возможность сократить код, но в общем случае объемные объекты строятся именно так, т. e. из отдельных плоских примитивов.

Рис.2. Построение куба в OpenGL

Для придания трехмерности сцене поворачиваем ее по осям:

procedure TfrmGL. FormResize(Sender: TObject); begin glViewport(0, 0, ClientWidth, ClientHeight); glLoadIdentity; glFrustum (-1, 1, -1, 1, 3, 10); // задаем перспективу // этот фрагмент нужен для придания трехмерности glTranslatef (0. 0, 0. 0, -8. 0); // перенос объекта - ось Z glRotatef (30. 0, 1. 0, 0. 0, 0. 0); // поворот объекта - ось X glRotatef (70. 0, 0. 0, 1. 0, 0. 0); // поворот объекта - ось Y InvalidateRect(Handle, nil, False); end;

Рис. 3. Придание трехмерности посредством поворота сцены

Рассмотрим команды, используемые в этом блоке кода.

Первая строка

glViewport(0, 0, ClientWidth, ClientHeight);

задает область вывода указанием координат левого нижнего и правого верхнего углов (в пикселах, в оконных координатах). Здесь в качестве области вывода используется вся клиентская часть окна.

Основная последовательность действий заключена между командами glPushMatrix и glPopMatrix. Если этого не делать, то при каждой перерисовке окна, например, при изменении его размеров, сцена будет уменьшаться в размерах.

Команда glFrustum задает параметры вида, в частности, определяющие область воспроизведения в пространстве и определяет перспективную проекцию. Все, что выходит за пределы этой области, будет отсекаться при воспроизведении.

Первые два аргумента задают координаты плоскостей отсечения слева и справа, третий и четвертый параметры определяют координаты плоскостей отсечения снизу и сверху. Последние аргументы задают расстояния до ближней и дальней плоскостей отсечения, значения этих двух параметров должны быть положительными, поскольку это не координаты плоскостей, а расстояния от глаза наблюдателя до плоскостей отсечения.

Чтобы лучше разобраться с этой командой библиотеки OpenGL, в приведенном примере в качестве аргументов команды передаются переменные:

glFrustum (vLeft, vRight, vBottom, vTop, vNear, vFar);

Нажатием на пробел можно приблизить точку зрения к сцене, если при этом удерживать клавишу <Shift>, точка зрения будет удаляться. Чтобы приблизить точку зрения, варьируем с помощью первых четырех аргументов параметры перспективы, уменьшая объем сцены, для удаления в пространстве проводим обратную операцию. Затем заново обращаемся к обработчику Resize формы, чтобы установить параметры перспективы в обновленные значения и перерисовать окно.

If Key = VK_SPACE then begin If ssShift in Shift then begin // нажат Shift, удаляемся vLeft: = vLeft - 0. 1; vRight: = vRight + 0. 1; vBottom: = vBottom - 0. 1; vTop: = vTop + 0. 1; end else begin // приближаемся vLeft: = vLeft + 0. 1; vRight: = vRight - 0. 1; vBottom: = vBottom + 0. 1; vTop: = vTop - 0. 1; end; FormResize(nil); end;

Аналогично клавишами управления курсором можно манипулировать значениями каждой из этих четырех переменных в отдельности, а клавиши <Insert> и <Delete> отвечают за координаты ближней и дальней плоскостей отсечения. Так, если чересчур близко к наблюдателю расположить заднюю плоскость отсечения, дальние ребра куба станут обрезаться.

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

Теперь все, что рисуется с нулевым значением координаты Z, не будет видно наблюдателю, поскольку ближнюю плоскость отсечения мы расположили на расстоянии трех единиц от глаза наблюдателя, располагающегося в точке (0, 0, 0). Поэтому перед воспроизведением треугольника смещаем систему координат на пять единиц вниз. Треугольник удалился от наблюдателя, и его вершины располагаются уже не на границе окна, а сместились вглубь экрана.

Далее выполняется перенос и поворот объекта относительно осей.

glTranslatef (0. 0, 0. 0, -8. 0); // перенос объекта - ось Z glRotatef (30. 0, 1. 0, 0. 0, 0. 0); // поворот объекта - ось X glRotatef (70. 0, 0. 0, 1. 0, 0. 0); // поворот объекта - ось Y

Получить параллельную проекцию позволяет команда glOrtho .

Аргументы команды glOrtho имеют точно такой же смысл, что и у glFrustum, но последние два аргумента могут иметь отрицательное значение. Помимо этих двух команд, OpenGL предоставляет еще несколько возможностей установки видовых параметров, например, библиотека glu содержит команду gluOrtho2D. Эта команда имеет четыре аргумента, смысл которых такой же, как и у glortho. По своему действию она эквивалентна вызову glOrtho с указанием значения расстояния до ближней плоскости отсечения равным минус единице, и расстоянием до дальней плоскости отсечения равным единице.

Команда gluPerspective наиболее популярна в плане использования для первоначального задания видовых параметров. Как ясно из ее названия, она также находится в библиотеке glu.

Procedure TfrmGL.FormResize(Sender: TObject); begin glViewport(0, 0, ClientWidth, ClientHeight); glLoadIdentity // задаем перспективу gluPerspective(30. 0, // угол видимости в направлении оси Y ClientWidth / ClientHeight, // угол видимости в направлении оси X 1 0, // расстояние от наблюдателя до ближней плоскости отсечения 15. 0); // расстояние от наблюдателя до дальней плоскости отсечения glTranslatef (0. 0, 0. 0, -10. 0); // перенос - ось Z glRotatef (30. 0, 1. 0, 0. 0, 0. 0); // поворот-ось X glRotatef (60. 0, 0. 0, 1. 0, 0. 0); // поворот-ось Y InvalidateRect (Handle, nil, False); end;

В проекте из подкаталога \Ex2 объединены все примеры на рассмотренные команды установки видовых параметров.