Студопедия — Перспективная проекция
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Перспективная проекция






Создайте новую копию файла и назовите ее glCube.cpp. Внимание! Начиная с этого задания, мы меняем стандартный каркас приложения. Отныне он будет рассчитан на трехмерную графику. Не спутайте его в следующих заданиях с каркасом для двухмерной графики.

В ортографической проекции (gluOrtho2D) мы в сущности создавали двухмерные изображения в плоскости z = 0. В других типах проекций (glOrtho и gluPerspective) мы можем создавать трехмерные изображения. Реальный эффект трехмерного пространства в двухмерной (плоской) проекции достигается с учетом перспективы. Теперь мы будем пользоваться только этим режимом передачи.

В OpenGL для обозначения видимого объема используется термин frustum. Он имеет латинское происхождение и примерно означает «отломанная часть, кусок». Frustum задается шестью плоскими границами типа (min, max) для каждой из трех пространственных координат. В перспективном режиме просмотра frustum — это усеченная пирамида, направленная на наблюдателя из глубины экрана. Все детали сцены, которые попадают внутрь этого объема, видны, а те, что выходят за него — отсекаются конвейером OpenGL. Другой режим просмотра — ортографический, или режим параллельной проекции, задается с помощью функции glOrtho. Он не учитывает перспективу, то есть при увеличении (удалении) координаты Z объекта от точки, в которой располагается наблюдатель, размеры объектов и углы между ними не изменяются, что напоминает плоские проекции объекта.

¨ Вставьте в обработчик WM_SIZE вместо строки:

gluOrtho2D (0., 1., 0., 1.);

строку:

gluPerspective (45, double(w)/h, 1, 100);

Первый параметр ее задает угол перспективы (угол обзора). Чем он меньше, тем больше увеличение. Вспомните школьные объяснения работы телескопа или бинокля, где использовались термины: фокусное расстояние и угол зрения. Последние два параметра функции gluPerspective задают переднюю и заднюю грани frustum'а — видимого объема. Он определяет замкнутый объем, за пределами которого отсекаются все элементы изображения. Боковые грани frustum'а определяютсмя с учетом дисбаланса (aspect ratio) двух размеров окна Мы вычисляем этот дисбаланс (double (w) / h) и подаем на вход функции gluPerspective в качестве второго параметра.

¨ Введите определения новых глобальных переменных:

double gdAngleX, gdAngleY; // Углы поворотов изображения вокруг осей X и Y

double gdTransX, gdTransY, gdTransZ = -4.; // Сдвиги вдоль координат

bool leftButton; // Нажата левая кнопка мыши

int giX, giY; // Текущая позиция указателя мыши

С их помощью мы будем транслировать (перемещать) изображения в трехмерном пространстве и вращать их вокруг двух осей. Включтите учет глубины, вставив в функцию Init вызов:

glEnable (GL_DEPTH_TEST);

Туда же вставьте установку режима заполнения полигонов.

glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);

При подготовке окна OpenGL и формата его пикселов надо установить бит GLUT_DEPTH — учета буфера глубины. Замените существующий вызов функции glutInitDisplayMode на:

glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);

В функции перерисовки мы создадим куб, координаты которого будем преобразовывать с помощью матрицы моделирования. Порядок работы с этой матрицей таков:

¨ Команда glMatrixMode (GL_MODELVIEW); выбирает в качестве текущей матрицу моделирования. Обычно при этом она сразу инициализируется единичной матрицей (см. вызов glLoadIdentity).

¨ Текущая матрица последовательно домножается справа на матрицы преобразования системы координат, которые формируются с помощью команд glTranslate (сдвиг), glRotate (вращение), glScale (растяжение-сжатие). Результат каждый раз помещается в текущую матрицу.

¨ Команды glVertex * генерируют вершины примитивов, то есть координатные векторы точек трехмерного пространства. Все эти векторы умножаются (справа) на текущюю матрицу моделирования и тем самым претерпевают преобразования, соответствующие желаемому местоположению и размерам объектов в сцене OpenGL.

Вершины всех примитивов в OpenGL заданы 4-х компонентным вектором (x, y, z, w). Четвертая компонента w помогает производить преобразования сдвига, вращения и масштабирования. По умолчанию она равна единице w = 1. При работе с двухмерными изображениями для всех вершин по умолчанию задается z = 0.

Window (x,y) (pixels)
Viewport (x,y) (-1,1,-1,1)
Viewer (x,y,z)
World (x,y,z)
glViewport
Матрица проецирования  
Матрица моделирования
Преобразование координат в OpenGL
3D
2D

В функции OnPaint, приведенной ниже, начальный поворот и последующие вращения вокруг оси Y осуществляется вызовом glRotated (gdAngleY, 0, 1, 0);. Аналогичный вызов glRotated (gdAngleX, 1, 0, 0); вращает все точки примитивов вокруг оси X.

void OnPaint()

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode (GL_MODELVIEW); // Будем пользоваться услугами матрицы моделирования

glLoadIdentity ();

glTranslated(gdTransX, gdTransY, gdTransZ); // Смещение координат точек будущих примитивов

glRotated(gdAngleY, 0, 1, 0); // Вращение координат точек будущих примитивов

glRotated(gdAngleX, 1, 0, 0);

 

static float v[8][3] = // Координаты точек куба (центр его в нуле)

{

-1, 1., -1., // 4 точки задней грани задаются

1., 1., -1., // в порядке против часовой стрелки

1., -1., -1.,

-1, -1., -1.,

-1, 1., 1., // 4 фронтальные точки

-1., -1., 1.,

1., -1., 1.,

1, 1., 1.

};

 

static double norm[6][3] = // 6 нормалей для 6-ти граней куба

{

0., 0., -1., // Rear

0., 0., 1., // Front

-1., 0., 0., // Left

1., 0., 0., // Right

0., 1., 0., // Top

0., -1., 0. // Bottom

};

 

static int id[6][4] = // Индексы вершин граней

{

0,1,2,3, // Rear (обход CCW - counterclockwise)

4,5,6,7, // Front

0,3,5,4, // Left

7,6,2,1, // Right

0,4,7,1, // Top

5,3,2,6, // Bottom

};

 

glColor3d (1, 0.4, 1);

glBegin(GL_QUADS);

 

for (int i = 0; i < 6; i++) // Долго готовились - быстро рисуем

{

glNormal3dv(norm[i]);

for (int j = 0; j < 4; j++)

glVertex3fv(v[id[i][j]]);

}

glEnd();

glFlush();

}

Запустите и отладьте приложение. Вы должны увидеть совсем плоский квадрат, несмотря на обещанную трехмерность объекта. Пока ничего вразумительного, никакого трехмерного эффекта. Закомментируйте или удалите (или измените на GL_SMOOTH) настройку glShadeModel (GL_FLAT); так как теперь мы хотим скрасить отсутствие трехмерности интерполяцией цветов при изображении полигонов. Это работает при задании разных цветов вершинам. Попробуйте задать всем вершинам разные цвета. Попробуйте покрутить изображение, изменяя значения переменных gdAngleX, gdAngleY. Например, вместо нулевых значений, присваиваемых глобальным переменным по умолчанию, задайте ненулевые.

Посмотрите в справке смысл всех параметров функции glRotate и опробуйте одновременное вращение вокруг двух осей, задав большее число единиц в качестве параметров. Позже мы автоматизируем процесс сдвигов и вращений, а сейчас, пока мы не умеем реагировать на сообщения мыши, просто измените значение какого-либо угла поворота и запустите приложение. Объясните результаты. Попробуйте отодвинуть изображение, изменив регулировку gdTransZ. Объясните знак смещения.







Дата добавления: 2015-10-19; просмотров: 650. Нарушение авторских прав; Мы поможем в написании вашей работы!



Композиция из абстрактных геометрических фигур Данная композиция состоит из линий, штриховки, абстрактных геометрических форм...

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

ТЕОРЕТИЧЕСКАЯ МЕХАНИКА Статика является частью теоретической механики, изучающей условия, при ко­торых тело находится под действием заданной системы сил...

Теория усилителей. Схема Основная масса современных аналоговых и аналого-цифровых электронных устройств выполняется на специализированных микросхемах...

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

Вопрос. Отличие деятельности человека от поведения животных главные отличия деятельности человека от активности животных сводятся к следующему: 1...

Расчет концентрации титрованных растворов с помощью поправочного коэффициента При выполнении серийных анализов ГОСТ или ведомственная инструкция обычно предусматривают применение раствора заданной концентрации или заданного титра...

ТРАНСПОРТНАЯ ИММОБИЛИЗАЦИЯ   Под транспортной иммобилизацией понимают мероприятия, направленные на обеспечение покоя в поврежденном участке тела и близлежащих к нему суставах на период перевозки пострадавшего в лечебное учреждение...

Кишечный шов (Ламбера, Альберта, Шмидена, Матешука) Кишечный шов– это способ соединения кишечной стенки. В основе кишечного шва лежит принцип футлярного строения кишечной стенки...

Принципы резекции желудка по типу Бильрот 1, Бильрот 2; операция Гофмейстера-Финстерера. Гастрэктомия Резекция желудка – удаление части желудка: а) дистальная – удаляют 2/3 желудка б) проксимальная – удаляют 95% желудка. Показания...

Studopedia.info - Студопедия - 2014-2024 год . (0.012 сек.) русская версия | украинская версия