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

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

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






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



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

Аальтернативная стоимость. Кривая производственных возможностей В экономике Буридании есть 100 ед. труда с производительностью 4 м ткани или 2 кг мяса...

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

Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

В теории государства и права выделяют два пути возникновения государства: восточный и западный Восточный путь возникновения государства представляет собой плавный переход, перерастание первобытного общества в государство...

Закон Гука при растяжении и сжатии   Напряжения и деформации при растяжении и сжатии связаны между собой зависимостью, которая называется законом Гука, по имени установившего этот закон английского физика Роберта Гука в 1678 году...

Характерные черты официально-делового стиля Наиболее характерными чертами официально-делового стиля являются: • лаконичность...

Понятие о синдроме нарушения бронхиальной проходимости и его клинические проявления Синдром нарушения бронхиальной проходимости (бронхообструктивный синдром) – это патологическое состояние...

Опухоли яичников в детском и подростковом возрасте Опухоли яичников занимают первое место в структуре опухолей половой системы у девочек и встречаются в возрасте 10 – 16 лет и в период полового созревания...

Способы тактических действий при проведении специальных операций Специальные операции проводятся с применением следующих основных тактических способов действий: охрана...

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