Иллюстрированный самоучитель по Visual Studio .NET

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

В ортографической проекции (giuOrtho2D) мы, в сущности, создавали двухмерные изображения в плоскости z = 0. В других типах проекций (gldrtho и gluPerspective) можно создавать трехмерные изображения. Эффект реального трехмерного пространства достигается в проекции с учетом перспективы. Теперь мы будем пользоваться только этим режимом передачи. Другой режим glOrtho вы опробуете самостоятельно, так как я не вижу какой-либо интересной сферы его применения. Вставьте в обработчик WM_SIZE вместо строки:

gluOrtho2D (0., double (w), 0., double(h));

Строку:

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

В OpenGL для обозначения видимого объема используется термин frustum. Он имеет латинское происхождение и примерно означает "отломанная часть, кусок".

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

Другой режим просмотра – ортографический, или режим параллельной проекции, задается с помощью функции glOrtho. Он не учитывает перспективу, то есть при увеличении (удалении) координаты Z объекта от точки, в которой располагается наблюдатель, размеры объектов и углы между ними не изменяются, что напоминает плоские проекции объекта. Первый параметр функции gluPerspective задает угол перспективы (угол обзора). Чем он меньше, тем больше увеличение. Вспомните школьные объяснения работы телескопа или бинокля, где были настройки фокусного расстояния, определяющего угол зрения.

Последние два параметра задают переднюю и заднюю грани видимого объема или frustum'a. Он определяет замкнутый объем, за пределами которого отсекаются все элементы изображения. Смотри иллюстрации в MSDN / Periodicals / Periodicals 96 / Microsoft System Journals/November / OpenGL Without the Pain. Боковые грани фрустума определяются с учетом дисбаланса двух размеров окна (отношения double(w) / double(h)). Мы вычисляем его и подаем на вход функции в качестве второго параметра.

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

//====== Углы поворотов изображения вокруг осей X и Y
double gdAngleX, gdAngleY; //====== Сдвиги вдоль координат
double gdTransX, gdTransY, gdTransZ = -4.;

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

glEnable(GL_DEPTH_TEST);

В функцию Init. Туда же вставьте установку режима заполнения полигонов:

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

И уберите строку, задающую текущий цвет вершин:

glColorSd (1., 0.4, 1.);

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

auxInitDisplayMode (AOX_SINGLE I AUX_RGB I AUX_DEPTH);

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

  • Сначала с помощью команды glMatrixMode (GL_MODELVIEW); матрица моделирования выбирается в качестве текущей. Обычно при этом она сразу инициализируется единичной матрицей (команда glLoadldentity).
  • После этого текущая (единичная) матрица последовательно домножается справа на матрицы преобразования системы координат, которые формируются с помощью команд glTranslate* (сдвиги), glRotate* (вращения) или glScale* (растяжения-сжатия).
  • Наконец, команды glVertex* генерируют вершины примитивов, то есть координатные векторы точек трехмерного пространства. Векторы умножаются (справа) на текущую матрицу моделирования и тем самым претерпевают такие преобразования, чтобы соответствовать желаемому местоположению и размерам в сцене OpenGL.
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.