Главная » Программирование игр под Android » ПЕРСПЕКТИВНАЯ ПРОЕКЦИЯ: БЛИЖЕ, БОЛЬШЕ – РАЗРАБОТКА ИГР ДЛЯ ОС ANDROID

0

 

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

Разницу между ортографической и перспективной проекциями можно объяснить, используя форму области видимости. При ортографической проекции она представляет собой прямоугольник. При перспективной проекции она имеет форму пирамиды, усеченной у ближней плоскости отсечения; основание пирамиды – это дальняя плоскость отсечения; ее грани – это левая, правая, верхняя и нижняя плоскости отсечения. На рис. 10.3 показана перспективная область видимости, сквозь которую мы можем просматривать сцену.

Рис. 10.3. Перспективная область видимости, содержащая сцену (слева), взгляд сверху на область видимости (справа)

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

Мы пока не рассматривали ни одной концепции, связанной с камерой. Мы просто считаем, что она неподвижна, находится в начале координат и направлена вдоль оси z в сторону отрицательных значений координат, что показано на рис. 10.3.

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

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

Ранее мы использовали метод gl Orthof , чтобы определить ортографическую область видимости в виде матрицы проекций. Для перспективной области видимости можем применить метод gl Frustumf . Однако есть и более простой способ.

Обычно OpenGL поставляется со вспомогательной библиотекой, которая называется GLU. Она содержит несколько вспомогательных функций для таких целей, как установка значений матрицы проекций и реализация систем камер. Эта библиотека также доступна на платформе Android, где она имеет вид класса, который тоже называется GLU. Она предоставляет несколько статических методов, которые можно вызвать без экземпляра класса GLU. Метод, который нас интересует в данный момент, называется gluPerspecti ve:

Этот метод перемножает текущую активную матрицу (например, проекционную или модельно-видовую) с матрицей перспективной проекции, как и метод gl Orthof . Первый параметр – это экземпляр класса GL10, обычно тот, который мы используем для всех остальных задач, связанных с OpenGL ES. Второй параметр – это поле зрения, заданное в углах, третий параметр – соотношение сторон окна просмотра, а последние два параметра определяют расстояние между позицией камеры и ближней, а также дальней областями отсечения. Поскольку у нас пока нет камеры, эти значения задаются относительно начала координат мира, заставляя нас смотреть в сторону отрицательных значений координат оси 2, как и на рис. 10.3. Это замечательно подходит для наших целей в данный момент. Мы убедимся, что все объекты, которые мы отрисовываем, останутся внутри фиксированной и неподвижной области видимости. Пока мы используемтолько метод gluPerspectiveO, мы не можем изменить позицию или ориентацию нашей виртуальной камеры. Мы всегда будем видеть только ту часть мира, которая лежит вдоль отрицательной половины оси 2.

Модифицируем последний пример так, чтобы в нем была использована перспективная проекция. Я просто скопировал весь код из класса Verti ces3Test в новый класс, который называется Perspecti veTest, а также переименовал Vertices3Screen в Perspecti veScreen. Единственное, что необходимо изменить, – метод present О. В листинге 10.3 показан новый код этого метода.

Листинг 10.3. Фрагменты класса PerspectiveTest.Java: перспективная проекция

Единственное отличие от предыдущего метода present  заключается в том, что теперь мы используем метод GLU. gl uPerspective вместо gl OrthoO. Мы применяем поле зрения, равное 67°, это значение близко к полю зрения человеческого глаза. Увеличивая или уменьшая это значение, вы сможете отобразить больше объектов слева и справа. Следующее, что мы определяем, – соотношение сторон, которое равно отношению ширины экрана к его высоте. Обратите внимание на то, что оно является числом с плавающей точкой, поэтому перед делением нам придется преобразовать ширину в тип f1oat. Последние аргументы – это расстояние между камерой и плоскостями отсечения. Полагая, что наша виртуальная камера находится в начале координат и направлена в сторону отрицательных значений по оси 2, все объекты, имеющие координату по оси 2, меньшую -0,1, но большую -10, будут находиться между ближней и дальней плоскостями отсечения и поэтому потенциально являются видимыми. На рис. 10.4 показан результат работы этого примера.

Рис. 10.4. Перспектива (в основном все верно)

Теперь мы на самом деле занимаемся ЗБ-графикой. Как вы можете видеть, у нас все еще есть проблема с порядком отрисовки треугольников. Исправим это с помощью всемогущего z-буфера.

Источник: Mario Zechner / Марио Цехнер, «Программирование игр под Android», пер. Егор Сидорович, Евгений Зазноба, Издательство «Питер»

По теме:

  • Комментарии