что такое мировая система координат
Представление геометрической информации
Поверхности свободных форм (функциональные модели)
Этот подход будет более подробно изложен в следующих главах.
В нашем курсе предполагается рассмотреть растровые алгоритмы для изображения таких геометрических примитивов, как отрезки, многоугольники, окружности и эллипсы. Но сначала мы займемся тем геометрическим аппаратом, который позволит адекватно описывать объекты в пространстве, работать с ними и формировать изображение.
Системы координат: мировая, объектная, наблюдателя и экранная
Видимый образ формируется на некоторой плоскости, которую в дальнейшем будем называть картинной плоскостью. Способы преобразования трехмерного объекта в двумерный образ ( проекции ) могут быть различными. Так или иначе, но полученный образ также должен быть описан в некоторой двумерной системе координат. В зависимости от способа его получения реальные размеры образа также могут быть различны. Различные виды проецирования будут подробно рассмотрены в последующих главах.
Поскольку нашей конечной целью является получение изображения на экране, то перенесение образа сопровождается изменением масштаба в соответствии с размерами экрана. Обычно началом координат в системе координат образа считается левый нижний угол листа с изображением. На экране дисплея начало координат традиционно находится в левом верхнем углу. Отображение рисунка с картинной плоскости на экран должно производиться с минимальным искажением пропорций, что само по себе вносит ограничение на область экрана, занимаемую рисунком. Изменение масштаба должно осуществляться с сохранением пропорций области (рис. 4.4).
Объекты в системе координат картинной плоскости задаются в каких- либо единицах измерения, причем масштаб одинаков по обеим осям координат. На экране единицей измерения является пиксель, который следует рассматривать как прямоугольный, поэтому масштабы по горизонтальной и вертикальной осям могут быть различны, что необходимо учитывать при задании коэффициентов масштабирования.
Рассмотрим ситуацию, когда изображение занимает на картинной плоскости прямоугольную область . При отображении рисунка на экран каждая точка исходного прямоугольника с координатами
перейдет в некоторую точку с целочисленными координатами
. Введем обозначения:
Системы координат в геодезии — какие бывают и как используются?
В данной статье мы разбираем основные вопросы по геодезии. Что такое системы координат, какие виды СК выделяют, какие из них используются на практике и для чего. А также, отвечаем на вопрос, почему мы предоставляем поправки в международной системе координат.
Содержание статьи:
Надеемся, этот материал поможет получить ответы на интересующие вопросы.
Что такое система координат?
Система координат (СК) — это набор математических правил, описывающих, как координаты должны быть соотнесены с точками пространства.
Иными словами, это совокупность условий, определяющих положение и перемещение точки или объекта на прямой, на плоскости, в пространстве с помощью чисел или других символов.
Совокупность чисел, определяющих положение точки, называется координатами этой точки.
Какие бывают системы координат?
Существуют разные геодезические системы координат, они используются в зависимости от масштаба, в котором необходимо произвести расчет расположения объекта на Земле.
В рамках данной статьи, разберемся, какие именно бывают системы координат и как используются на практике в геодезии.
Полярная система координат (полярные координаты)
Полярная система координат — это система координат, положение точки в которой задается расстоянием и направлением от ее начала.
Двумерная полярная система координат может быть задана на плоскости, поверхности сферы или эллипсоида.
Плоская прямоугольная (прямолинейная система координат)
Плоская прямоугольная (прямолинейная) система координат — это система координат, определяющая положение точек по отношению к взаимно перпендикулярным осям, исходящим из ее начала.
Координаты точки в данной системе координат представлены в виде плоских прямоугольных координат x и y. В геодезии — это координаты на плоскости, на которой отображена поверхность земного эллипсоида в заданной картографической проекции.
Прямоугольная пространственная система координат
Прямоугольная пространственная система координат — это система трехмерных линейных прямоугольных координат по координатным осям Х, У, Z координат, у которой оси Х и У лежат в экваториальной плоскости, ось Х направлена к начальному меридиану, ось Z направлена на север, орты образуют правую тройку векторов, а начало координат совпадает с центром земного эллипсоида.
Координаты точки в пространственной системе координат представлены в виде геодезических (эллипсоидальных) координатах или в прямоугольных пространственных координатах.
Земные и референцные системы координат
Помимо вышеупомянутых, различают земные (общеземные) и референцные системы координат. Разбираемся, чем они отличаются.
Что такое земная система координат в геодезии?
Земная система координат — это пространственная система координат, предназначенная для количественного описания положения и движения объектов, находящихся на поверхности Земли и в околоземном пространстве.
Что такое референцная система координат в геодезии?
Референцная система координат — это система координат, созданная с целью обеспечения геодезических и картографических работ на конкретной территории. К ним можно отнести местные и условные системы координат.
Что такое геодезическая система координат?
Геодезическая система координат — это система координат, которая используется для определения точного местоположения объекта на земном шаре.
За земной шар, для удобства проведения математических расчетов в инженерной геодезии, принимают шар с R=6371.11 км. Объем земного шара при этом равен объему земного эллипсоида.
Что такое геодезические координаты?
Геодезические координаты — это величины, два из которых (геодезическая широта B и геодезическая долгота L) характеризуют направление нормали к поверхности отсчетного эллипсоида в данной точке пространства относительно плоскостей его экватора и начального меридиана, а третий (геодезическая высота H) представляет собой высоту точки над поверхностью отсчетного эллипсоида.
В земных системах координат центр координат совпадает с центром масс Земли, поэтому прямоугольные пространственные координаты называют геоцентрическими координатами.
Системы координат также подразделяют на государственные, местные, локальные и международные.
СК, используемые на практике
Практическими реализациями пространственной геоцентрической земной системы координат являются системы координат WGS-84, ПЗ-90.11 и ГСК-2011.
Система координат WGS-84
WGS-84 (World Geodetic System (Всемирная геодезическая система координат)) – это система геодезических параметров Земли 1984 года, используемая в GPS, в число которых входит система геоцентрических координат).
Система координат ПЗ-90.11
ПЗ-90.11 (общеземная геоцентрическая система координат «Параметры Земли 1990 года») — это государственная система координат, используемая в ГЛОНАСС.
ПЗ-90.11 была установлена постановлением Правительства РФ от 24 ноября 2016 года №1240 для использования в целях геодезического обеспечения орбитальных полетов, решения навигационных задач и выполнения геодезических и картографических работ в интересах обороны Российской Федерации.
Система координат ГСК-2011
ГСК-2011 (геодезическая система координат 2011 года) – это государственная система координат, установленная постановлением Правительства РФ от 24 ноября 2016 года №1240 для использования при осуществлении геодезических и картографических работ на территории Российской Федерации.
Система координат МСК
МСК – это местная система координат субъекта Российской Федерации, установленная для целей обеспечения проведения геодезических и картографических работ при осуществлении градостроительной и кадастровой деятельности, землеустройства, недропользования и иной деятельности.
Каждый субъект имеет свою МСК с номером данного субъекта, например, местная система координат Московской области именуется МСК-50.
Архивные системы координат
Существуют архивные системы координат, которые в настоящее время не используются (не действуют).
Среди них можно выделить:
Какие бывают системы отсчета высот?
Высоты в геодезии могут быть представлены в виде геодезических, ортометрических и нормальных и высот. Высоты также могут быть представлены в условной системе высот.
Основные системы отсчета высот:
Отсчет высот в Балтийской системе высот 1977 года ведется от нуля Кронштадтского футштока, укрепленного в устое моста через обводной канал в г. Кронштадте.
Почему мы предоставляем поправки в международной системе координат?
Поскольку ГНСС работают в реализациях земной геоцентрической системы координат, таких как WGS-84 и ПЗ-90.11, то первоначально все спутниковые определения с использованием ГНСС выполняются в этих системах координат.
В ГНСС аппаратуре и программном обеспечении все результаты (координаты, скорости, ускорения) вначале приводятся в WGS-84, которые можно представить в любой другой системе координат путем математических преобразований.
Координаты в пространственных земных системах WGS-84, ПЗ-90.11 или ГСК-2011 с точностью 1 метр практически совпадают, поэтому для спутниковых определений с такой точностью не имеет значения в какой из реализаций системы координат они представлены.
Для спутниковых определений с высокой точностью мы предоставляем дифференциальные поправки, которые применяются к измеряемым величинам в процессе спутниковых определений. Дифференциальные поправки позволяют определить пространственные координаты относительно спутниковых базовых станций с заданными координатами.
Поскольку в нашей сети координаты всех станций определены в международной системе координат WGS-84, координаты определяемых вами точек также первоначально представлены в WGS-84. Но, как уже было сказано выше, они могут быть преобразованы в любую системы координат по известным параметрам преобразования.
learnopengl. Урок 1.8 — Системы координат
Преобразование координат в нормализованные, а затем в экранные координаты обычно осуществляется пошагово, и, до окончательного преобразования в экранные координаты, мы переводим вершины объекта в несколько координатных систем. Преимущество преобразования координат через несколько промежуточных координатных систем заключается в том, что некоторые операции/вычисления проще выполняются в определённых системах, и это скоро станет очевидно. Всего есть 5 различных координатных систем, которые для нас важны:
Наши вершины будут преобразованы во все эти различные состояния, прежде чем превратятся во фрагменты.
Вероятно сейчас вы совершенно запутаны тем, что каждое пространство или координатная система из себя представляют, поэтому мы рассмотрим их в более понятном виде показав общую картину и то, что каждое из пространств действительно делает.
Общая схема
Для преобразования координат из одного пространства в другое, мы будем использовать несколько матриц трансформации, среди которых, самыми важными являются матрицы Модели, Вида и Проекции. Координаты наших вершин начинаются в локальном пространстве как локальные координаты, и в дальнейшем преобразуются в мировые координаты, потом в координаты вида, отсечения, и, наконец, все заканчивается экранными координатами. Следующее изображение показывает эту последовательность, и то, что делает каждое преобразование:
После всего этого, полученные координаты отсылаются растеризатору для превращения их во фрагменты.
Вероятно вы уже немного поняли, для чего используется каждое координатное пространство. Причина, по которой мы преобразуем наши вершины в эти различные координатные пространства, заключается в том, что некоторые операции становятся более понятными или более простыми в определенных координатных системах.
Например, модификацию вашего объекта разумнее всего выполнять в локальном пространстве, а вычисление операций учитывающих расположение других объектов лучше делать в мировых координатах, и т.д. При желании мы могли бы задать одну матрицу трансформации, которая преобразовывала координаты из локального пространства в пространство Отсечения за один шаг, но это лишит нас гибкости.
Ниже мы обсудим каждую координатную систему более подробно.
Локальное пространство
Локальное пространство это координатная система, которая является локальной для объекта, т.е. начинается в той же точке, что и сам объект. Представьте, что вы создали куб в программном пакете моделирования (подобном Blender). Начальная точка вашего куба вероятно расположена в (0,0,0), даже несмотря на то, что куб в координатах приложения может находиться в другом месте. Возможно, что все созданные вами модели имеют начальную точку (0,0,0). Следовательно, все вершины вашей модели находятся в локальном пространстве: все их координаты являются локальнми по отношению к вашему объекту.
Мировое пространство
Если мы напрямую импортируем все наши объекты в приложение, то они вероятно окажутся нагроможденными друг на друга около мировой точки отсчета (0,0,0), а это совсем не то, что мы хотим. Нам нужно определить положение каждого объекта для размещения их в более обширном пространстве. Координаты в мировом пространстве, это как раз то, о чем говорит их название: координаты всех ваших вершин относительно (игрового) мира. Это координатное пространство, в котором вы бы хотели видеть ваши объекты преобразованными таким образом, что бы они были распределены в пространстве (и желательно реалистично). Координаты вашего объекта преобразуются из локального в мировое пространство; это выполняется посредством матрицы модели.
Матрица модели это матрица, которая перемещает, масштабирует и/или вращает ваш объект для его расположения в мировом пространстве в позиции/ориентации в которой объект должен находиться. Представьте себе это как трансформацию здания, которому изменили масштаб (оно было слишком большим в локальном пространстве), перенесли его в пригород, и немного повернули влево по оси Y таким образом, что оно точно подошло к соседним домам. Вы можете воспринимать матрицу из предыдущего урока, в котором мы перемещали контейнер по сцене, как разновидность матрицы модели; с её помощью мы пересчитывали локальные координаты контейнера для размещения его в разных местах сцены/мира.
Пространство Вида
Пространство Вида это то, что люди обычно называют камерой OpenGL (иногда оно также называется пространство камеры или наблюдателя). Пространство вида это результат преобразования мировых координат в координаты, которые выглядят, как будто пользователь смотрит на них спереди. Таким образом пространство вида — это пространство видимое через видоискатель камеры. Это обычно достигается совокупностью таких сдвигов и вращений сцены, что некоторые объекты располагаются перед камерой. Эти комбинированные преобразования как правило хранятся в матрице вида, которая трансформирует мировые координаты в пространство вида. В следующем уроке мы широко обсудим, как создавать такую матрицу вида, для имитации камеры.
Пространство Отсечения
После завершения работы вершинных шейдеров, OpenGL ожидает, что все координаты будут в определенном диапазоне, а всё что выходит за его границы будет отсечено. Отсеченные координаты отбрасываются, а оставшиеся становятся фрагментами, видимыми на экране. Вот откуда пространство отсечения получило своё название.
Задавать все видимые координаты значениями из диапазона [-1.0, 1.0] на самом деле интуитивно непонятно, поэтому для работы мы определяем свой собственный набор координат и потом преобразовываем их обратно в NDC, как того ожидает OpenGL.
Обратите внимание на то, что если вне объема отсечения находится не весь примитив, например треугольник, а только его часть, то OpenGL перестроит этот треугольник в виде одного или нескольких треугольников, которые будут полностью находиться в диапазоне отсечения.
Этот объем просмотра, задаваемый матрицей проекции, называется усечённой пирамидой (frustum) и каждая координата попадающая в эту пирамиду окажется и на экране пользователя. Весь процесс конвертации координат определенного диапазона в нормализованные координаты устройства (NDC), которые могут с легкостью отображены в двумерные координаты пространства вида, называется проецирование, так как матрица проекции проецирует 3D координаты на простые-для-преобразования-в-2D нормализованные координаты устройства.
Как только координаты всех вершин будут переведены в пространство отсечения, выполняется заключительная операция, называемая перспективное деление. В ней мы делим x,y и z компоненты вектора позиции вершины на гомогенную компоненту вектора w. Перспективное деление преобразует 4D координаты пространства отсечения в трехмерные нормализованные координаты устройства. Этот шаг выполняется автоматически после завершения работы каждого вершинного шейдера.
Именно после этого этапа, полученные координаты (используя установки glViewport) отображаются на координаты экрана и превращаются во фрагменты.
Матрица проекции преобразующая координаты вида в координаты отсечения может принимать две различных формы, и каждая форма определяет свою особенную усеченную пирамиду. Мы можем создать ортографическую матрицу проекции или перспективную.
Ортографическая проекция
Матрица ортографической проекции задает усечённую пирамиду в виде параллелограмма, который является пространством отсечения, где все вершины, находящиеся вне его объема отсекаются. При создании матрицы ортографической проекции мы задаем ширину, высоту и длину видимой пирамиды отсечения. Все координаты, которые после их преобразования матрицей проекции в пространство отсечения попадают в ограниченный пирамидой объем отсечены не будут. Усеченная пирамида выглядит немного похожей на контейнер:
Усеченная пирамида определяет область видимых координат и задается шириной, высотой, ближней и дальней плоскостями. Любая координата, расположенная перед ближней плоскостью, отсекается, точно также поступают и с координатами, находящимися за задней плоскостью. Ортографическая усеченная пирамида напрямую переводит попадающие в неё координаты в нормализованные координаты устройства, и w-компоненты векторов не используются; если w-компонент равен 1.0, то перспективное деление не изменит значений координат.
Для создания матрицы ортографической проекции мы используем встроенную функцию библиотеки GLM, которая называется glm::ortho:
Первые два параметра определяют левую и правую координаты усеченной пирамиды, а третий и четвертый параметры задают нижнюю и верхнюю границы пирамиды. Эти четыре точки устанавливают размеры ближней и дальней плоскостей, а 5-й и 6-й параметры указывают расстояние между ними. Эта особая матрица проекции преобразует все координаты попадающие в диапазоны значений x, y и z, в нормализованные координаты устройства.
Ортографическая матрица проекции отображает координаты непосредственно на двумерную плоскость, которой является ваш дисплей, но в действительности, прямое проецирование дает нереалистичные результаты, потому что не принимает в расчет перспективы. Это исправляет матрица перспективной проекции.
Перспективная проекция
Если вы когда-либо наблюдали за реальным миром, то наверняка заметили, что объекты, расположенные дальше, выглядят намного меньше. Этот странный эффект мы называем перспективой. Перспектива особенно заметна, когда смотришь в конец бесконечной автомагистрали или железной дороги, как это видно на следующем изображении:
Каждый компонент координаты вершины делится на свою w-компоненту, что уменьшает значения координат пропорционально удалению от зрителя. Это еще одна причина важности w-компонента, поскольку он помогает нам с перспективной проекцией. Полученные после этого координаты находятся в нормализованном пространстве устройства. Если вам интересно разобраться, как рассчитываются ортогональные и перспективные матрицы проекции (и вы не слишком боитесь математики), то могу порекомендовать эту отличную статью Songho.
Матрицу перспективной проекции в библиотеке GLM можно создать следующим образом:
glm::perspective создает усеченную пирамиду, которая определяет видимое пространство, а все, что находится за его пределами и не попадет в объем пространства отсечения будет обрезано. Перспективная усеченная пирамида может быть представлена как коробка трапециевидной формы, каждая координата внутри которой будет отображена в точку в пространстве отсечения. Изображение перспективной усеченной пирамиды показано ниже:
Первый параметр устанавливает значение fov (field of view), что обозначает «поле обзора«, и определяет, насколько велика видимая область. Для реалистичного представления этот параметр обычно устанавливается равным 45.0f, но для получения подобия doom-стилю вы можете задавать и большие значения. Второй параметр задает соотношение сторон, которое рассчитывается путем деления ширины области просмотра на её высоту. Третий и четвертый параметры задают ближнюю и дальнюю плоскости усеченной пирамиды. Обычно мы устанавливаем ближайшее расстояние равным 0.1f, а дальнее 100.0f. Все вершины расположенные между ближней и дальней плоскостью и попадающие в объем усеченной пирамиды будут визуализированы.
Если в матрице проекции расстояние до ближней плоскости будет задано слишком большим (например, 10.0f), то OpenGL отсечет все координаты, расположенные рядом с камерой (между 0.0 и 10.0f), что дает знакомый по видео-играм визуальный эффект, когда вы можете видеть сквозь некоторые предметы если подходите к ним слишком близко.
При использовании ортогональной проекции каждая координата вершины непосредственно отображается в пространство отсечения без какого-либо мнимого перспективного деления (перспективное деление производится, но w-компонент на результат никак не влияет (он остается равен 1) и, следовательно, не имеет никакого эффекта). Поскольку ортографическая проекция не учитывает перспективу, то объекты, расположенные дальше, не кажутся меньше, что создает странное визуальное впечатление. По этой причине ортографическая проекция в основном используется для 2D-рендеринга и различных архитектурных или инженерных приложений, где мы бы предпочли отсутствие искажений, обусловленных перспективой. В таких приложениях, как Blender, предназначенных для 3D-моделирования, ортографическая проекция иногда используется во время моделирования, потому что она более точно отображает измерения и пропорции каждого объекта. Ниже приведено сравнение обоих проекционных методов в Blender:
Вы можете видеть, что при перспективной проекции удаленные вершины оказываются намного дальше, в то время как в ортографической проекции скорость удаления вершин одинаковая и не зависит от расстояния до наблюдателя.
Собираем все вместе
Создадим матрицу преобразования для каждого из вышеупомянутых шагов: модели, вида и матрицы проекции. Координата вершины преобразуется в координаты пространства отсечения следующим образом:
Обратите внимание, что порядок умножения матриц обратный (помните, что умножение матриц нужно читать справа налево). Полученная координата вершины должна быть присвоена в вершинном шейдере встроенной переменной gl_Position, после чего OpenGL автоматически выполнит перспективное деление и отсечение.
Что потом?
Координаты выходных данных вершинного шейдера должны находиться в пространстве отсечения, чего мы только что и добились с помощью матриц преобразования. OpenGL выполняет перспективное деление координат пространства отсечения, чтобы преобразовать их в нормализованные координаты устройства
Затем OpenGL использует параметры из glViewPort для сопоставления нормализованных координат устройства экранными координатами, в которых каждая координата соответствует точке на вашем экране (в нашем случае это область 800×600). Этот процесс называется преобразованием области просмотра.
Это тема трудна для понимания, поэтому, если вы все еще не совсем уверены в том, для чего используется каждое пространство, то вам не нужно беспокоиться.
Ниже вы увидите, как мы сможем эффективно применять эти координатные пространства, и в дальнейших уроках будет достаточно примеров.
Переходим к 3D
Теперь, когда мы знаем, как преобразовать 3D-координаты в 2D-координаты, мы можем начать отображать наши объекты в виде реальных 3D-объектов, а не ущербных 2D-плоскостей, которые мы показывали до сих пор.
Для начала рисования в 3D мы первым делом создадим матрицу модели. Матрица модели состоит из сдвигов, масштабирования и/или поворотов, которые мы бы хотели применить, чтобы преобразовать все вершины объекта в глобальное мировое пространство. Давайте немного изменим нашу плоскость, повернув ее по оси X, чтобы она выглядела так, будто лежит на полу. Матрица модели будет выглядеть следующим образом:
Умножив координаты вершин на эту матрицу модели мы преобразуем их в мировые координаты. Наша плоскость лежащая на полу, представляет собой таким образом плоскость в мировом пространстве.
Затем нам нужно создать матрицу вида. Чтобы объект стал видимым нам нужно немного сдвинуться в сцене назад (потому что точка зрения наблюдателя в мировом пространстве находится в начале координат (0,0,0)). Для перемещения по сцене, подумайте о следующем:
Сдвиг камеры назад — это то же самое, что перемещение всей сцены вперед.
Это именно то, что делает матрица вида: мы перемещаем всю сцену в сторону противоположную той, в которую бы мы хотели сдвинуть камеру. Так как нам нужно двигаться назад, и поскольку OpenGL использует правую систему координат, то мы должны перемещаться в положительном направлении оси z. Мы осуществляем это, сдвигая всю сцену в отрицательную сторону оси z. Это создает впечатление, что мы движемся назад.
По соглашению, OpenGL является правой координатной системой. В основном это говорит о том, что положительная ось X направлена в право от вас, положительная ось Y вверх, а положительная ось Z на вас (т.е назад). Представьте, что ваш экран является центром трех осей, и положительная ось Z проходит через экран по направлению к вам. Оси изображаются таким образом:
Чтобы понять, почему эта система называется правой, сделайте следующее:
Если вы все сделали правильно, то ваш большой палец должен указывать направление положительной оси X, указательный палец — положительную ось Y, а средний палец на положительную ось z. Если вы проделаете то же самое левой рукой, то увидите, что ось Z изменит направление. Такая система координат известна как левая и обычно используется в DirectX. Обратите внимание, что в нормализованных координатах устройства OpenGL фактически использует левую систему (матрица проекции переключает направление).
Мы обсудим перемещение по сцене более подробно в следующем уроке. На данный момент матрица вида выглядит так:
Последнее, что нам нужно определить — это матрица проекции. Для нашей сцены мы будем использовать перспективную проекцию, поэтому объявим матрицу следующим образом:
Будьте внимательны при указании градусов в GLM. Здесь мы устанавливаем параметр fov равным 45 градусам, но некоторые реализации GLM принимают fov в радианах, в этом случае вам нужно задать его как glm::radians(45.0).
Теперь, когда мы создали матрицы преобразования, мы должны передать их нашим шейдерам. Сначала давайте объявим в вершинном шейдере матрицы преобразования как uniform и умножим их на координаты вершин:
Мы также должны отправить матрицы в шейдер (обычно это делается для каждой итерации, так как матрицы преобразования имеют тенденцию часто меняться):
Теперь, когда наши координаты вершин преобразуются матрицами модели, вида и матрицей проекции, конечный объект должен:
Давайте проверим, действительно ли результат соответствует этим требованиям:
Это и правда похоже на 3D-плоскость, которая покоится на каком-то воображаемом полу. Если вы не получили такого же результата, проверьте полный исходный код, вершинный шейдер и фрагментный шейдер.
Больше 3D
До сих пор мы работали с 2D-плоскостью, но в 3D-пространстве, поэтому давайте совершим небольшое приключение и расширим нашу 2D-плоскость до 3D-куба.
Для отображения куба нам в общей сложности потребуется 36 вершин (6 сторон * по 2 треугольника * по 3 вершины в каждом). Набрать 36 вершин это довольно много, так что вы можете взять их здесь. Обратите внимание, что для получения результирующего цвета фрагментов мы будем пользоваться только текстурой, поэтому значения цвета вершин мы пропускаем.
Удаление из массива вершин атрибутов цвета меняет размер «шага» между вершинами, поэтому необходимо исправить этот параметр в вызовах функции glVertexAttribPointer:
Для разнообразия зададим кубу вращение:
И теперь нарисуем куб используя glDrawArrays, но на этот раз с количеством 36 вершин.
Вы должны получить что-то похожее на это:
Объект немного похож на куб, но что-то с ним не так. Некоторые стороны куба рисуются поверх других его сторон. Это происходит потому, что, когда OpenGL визуализирует ваш куб треугольник-за-треугольником, он перезаписывает находящиеся в буфере кадров пиксели, несмотря на его содержимое и то, что уже было нарисовано в нём до этого. Из-за этого некоторые треугольники рисуются один поверх другого, хотя они не должны перекрывать друг друга.
К счастью, OpenGL хранит информацию о глубине в буфере под названием Z-буфер, который позволяет OpenGL решить, когда рисовать поверх пикселя, а когда нет. С помощью Z-буфера, мы можем настроить OpenGL делать проверку глубины пикселей.
Z-буфер
OpenGL хранит всю информацию о глубине в Z-буфере, также известном как буфер глубины. GLFW создает это буфер автоматически (он так же имеет буфер кадра, который хранит цвета выходного изображения). Глубина хранится для каждого фрагмента (в качестве z-значения) и всякий раз, когда фрагмент выводит свой цвет, OpenGL сравнивает его значение глубины со значениями из Z-буфера, и если текущий фрагмент находится позади другого фрагмента он отбрасывается, а в противном случае перезаписывается. Этот процесс называется проверка глубины и осуществляется OpenGL автоматически.
Тем не менее, если мы хотим быть уверены в том, что OpenGL действительно выполняет проверку глубины, то сначала нам нужно её включить, потому что по-умолчанию она выключена. Включение проверки глубины осуществляется с помощью функции glEnable. Функции glEnable и glDisable позволяют включить/отключить определенные возможности OpenGL. Опции OpenGL включаются/выключаются, пока не будет сделан другой вызов функции для их отключения/включения. На данный момент мы хотим разрешить проверку глубины, включая параметр GL_DEPTH_TEST:
Так как мы используем буфер глубины, то нам нужно его очищать перед каждой итерацией визуализации (в противном случае в буфере останется информация о глубине предыдущих кадров). Мы можем очистить буфер глубины таким же образом как и буфера цвета, указав в функции glClear бит GL_DEPTH_BUFFER_BIT:
Давайте повторно запустим нашу программу и посмотрим, выполняет ли теперь OpenGL проверку глубины:
Вот и всё! Наш куб полностью текстурирован, с правильной проверкой глубины, еще и вращается. Здесь исходный код для проверки.
Больше кубиков!
Предположим, что мы хотели бы отобразить на экране 10 наших кубов. Все кубы выглядят одинаково, но будут отличаться местоположением в мировом пространстве и углом поворота. Графическое представление куба уже определено, и для того, чтобы нарисовать еще несколько объектов нам уже не нужно менять буферы или массивы атрибутов. Единственное, что мы должны исправить для каждого объекта — это его матрицу модели, благодаря которой мы преобразуем локальные координаты куба в мировые.
Во-первых, давайте определим для каждого куба вектор перемещения, который задаст положение объекта в мировом пространстве. Мы запишем 10 позиций кубов в массиве glm::vec3:
Теперь, в рамках игрового цикла мы собираемся вызвать функцию glDrawArrays 10 раз, но при этом перед каждой визуализацией будем передавать в вершинный шейдер разные матрицы модели. Мы создадим внутри игрового цикла еще один небольшой цикл, который нарисует наш объект 10 раз с разными значениями матрицы модели. Обратите внимание, что для каждого контейнера мы также добавили небольшое вращение.
Этот фрагмент кода будет обновлять матрицу модели при каждом изображении нового куба, и всего сделает это 10 раз. Сейчас мы должны видеть мир, заполненный десятью произвольно повернутыми кубами:
Отлично! Похоже, наш контейнер нашел несколько похожих на него друзей. Если вы застряли, то прежде чем продолжить посмотрите в чем может быть проблема и сравните свой код с исходным кодом, вершинным и фрагментным шейдером.