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

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

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






Создайте новую копию файла и назовите ее 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; просмотров: 655. Нарушение авторских прав; Мы поможем в написании вашей работы!



Шрифт зодчего Шрифт зодчего состоит из прописных (заглавных), строчных букв и цифр...

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

Практические расчеты на срез и смятие При изучении темы обратите внимание на основные расчетные предпосылки и условности расчета...

Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...

Типовые примеры и методы их решения. Пример 2.5.1. На вклад начисляются сложные проценты: а) ежегодно; б) ежеквартально; в) ежемесячно Пример 2.5.1. На вклад начисляются сложные проценты: а) ежегодно; б) ежеквартально; в) ежемесячно. Какова должна быть годовая номинальная процентная ставка...

Выработка навыка зеркального письма (динамический стереотип) Цель работы: Проследить особенности образования любого навыка (динамического стереотипа) на примере выработки навыка зеркального письма...

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

Менадиона натрия бисульфит (Викасол) Групповая принадлежность •Синтетический аналог витамина K, жирорастворимый, коагулянт...

Разновидности сальников для насосов и правильный уход за ними   Сальники, используемые в насосном оборудовании, служат для герметизации пространства образованного кожухом и рабочим валом, выходящим через корпус наружу...

Дренирование желчных протоков Показаниями к дренированию желчных протоков являются декомпрессия на фоне внутрипротоковой гипертензии, интраоперационная холангиография, контроль за динамикой восстановления пассажа желчи в 12-перстную кишку...

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