OpenGL определяет положение вершины в пикселях - PullRequest
24 голосов
/ 11 сентября 2011

Я писал двумерный базовый игровой движок на OpenGL / C ++ и изучал все по ходу дела. Я все еще довольно озадачен определением вершин и их «положением». То есть я все еще пытаюсь понять механизм преобразования вершин в пиксели в OpenGL. Это может быть объяснено кратко или кто-то может указать на статью или что-то, что объяснит это. Спасибо!

Ответы [ 5 ]

27 голосов
/ 11 сентября 2011

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

  1. Позиция вершины преобразуется из объектного пространства (локального для некоторого объекта) в мировое пространство (относительно некоторой глобальной системы координат),Это преобразование указывает, где находится ваш объект (которому принадлежат вершины) в мире

  2. Теперь позиция в мировом пространстве преобразуется в камеру / пространство обзора.Это преобразование определяется положением и ориентацией виртуальной камеры, с помощью которой вы видите сцену.В OpenGL эти два преобразования фактически объединены в одну, матрицу просмотра модели, которая напрямую преобразует ваши вершины из пространства объектов в пространство просмотра.

  3. Затем применяется преобразование проекции.Принимая во внимание, что преобразование вида модели должно состоять только из аффинных преобразований (вращение, перемещение, масштабирование), проекционное преобразование может быть перспективным, которое в основном искажает объекты, чтобы реализовать реальный вид в перспективе (с меньшими объектами).Но в вашем случае 2D-вида это, вероятно, будет ортографическая проекция, которая не делает ничего, кроме перевода и масштабирования.Это преобразование представлено в OpenGL матрицей проекции.

  4. После этих 3 (или 2) преобразований (а затем после деления перспективы на компонент w, который фактически реализует искажение перспективы, еслилюбой) то, что у вас есть, это нормализованные координаты устройства.Это означает, что после этих преобразований координаты видимых объектов должны находиться в диапазоне [-1,1].Все, что находится за пределами этого диапазона, обрезается.

  5. На последнем шаге применяется преобразование области просмотра, и координаты преобразуются из диапазона [-1,1] в куб [0,w]x[0,h]x[0,1] (в предположении glViewport(0, w, 0, h) call), которые представляют собой конечные позиции вершины в кадровом буфере и, следовательно, ее пиксельные координаты.

При использовании вершинного шейдера шаги с 1 по 3 фактически выполняются в шейдере ипоэтому может быть сделано любым способом, который вам нравится, но обычно он соответствует этому стандартному виду модели -> конвейеру проекции.

Главное, что нужно иметь в виду, что после просмотра модели и проекции каждая вершина преобразуется скоординаты вне диапазона [-1,1] будут отсечены.Таким образом, поле [-1,1] определяет вашу видимую сцену после этих двух преобразований.

Итак, из вашего вопроса я предполагаю, что вы хотите использовать 2D-систему координат с единицами пикселей для ваших координат вершин и преобразований?В этом случае это лучше всего сделать, используя glOrtho(0.0, w, 0.0, h, -1.0, 1.0), где w и h - это размеры вашего окна просмотра.Это в основном противостоит преобразованию области просмотра и, следовательно, преобразует ваши вершины из [0,w]x[0,h]x[-1,1] -бокса в [-1,1] -бокс, который преобразование окна просмотра затем преобразует обратно в [0,w]x[0,h]x[0,1] -бокс.

Они былидовольно общие объяснения, не говоря уже о том, что фактические преобразования выполняются умножением матрицы на вектор и не говоря об однородных координатах, но они должны были объяснить основные моменты.Эта документация по gluProject может также дать вам некоторое представление, поскольку она фактически моделирует конвейер преобразования для одной вершины.Но в этой документации они на самом деле забыли упомянуть деление на компонент w (v" = v' / v'(3)) после шага v' = P x M x v.

РЕДАКТИРОВАТЬ: Не забудьте взглянуть на первая ссылка в ответе эпателя, который объясняет конвейер преобразования немного более практичным и подробным.

12 голосов
/ 11 сентября 2011

Это называется трансформацией.

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

http://www.songho.ca/opengl/gl_transform.html

http://www.opengl.org/wiki/Vertex_Transformation

http://www.falloutsoftware.com/tutorials/gl/gl5.htm

3 голосов
/ 11 сентября 2011

Во-первых, имейте в виду, что OpenGL не использует стандартные пиксельные координаты. Я имею в виду, что для конкретного разрешения, т.е. 800x600 У вас нет горизонтальных координат в диапазоне 0-799 или 1-800 с шагом в один. Скорее, координаты в диапазоне от -1 до 1 позже отправляются в модуль растрирования графической карты и после этого соответствуют определенному разрешению.

Я пропустил один шаг здесь - прежде всего, что у вас есть матрица ModelViewProjection (или матрица viewProjection в некоторых простых случаях), которая прежде всего будет приводить координаты, которые вы используете, к плоскости проекции. По умолчанию это используется для реализации камеры, которая преобразует трехмерное пространство мира (вид для размещения камеры в правильное положение и проекция для приведения трехмерных координат в плоскость экрана. В ModelViewProjection это также шаг размещения модели в нужном месте в мире).

Другой случай (и вы можете использовать матрицу проекции таким образом, чтобы достичь желаемого) - это использование этих матриц для преобразования одного диапазона разрешений в другой.

И тебе понадобится трюк. Вы должны прочитать о матрице модели ViewProjection и камере в openGL, если хотите серьезно. Но сейчас я скажу вам, что с правильной матрицей вы можете просто привести свою собственную систему координат (то есть использовать диапазоны 0-799 по горизонтали и 0-599 по вертикали) в стандартизированный диапазон -1: 1. Таким образом, вы не увидите, что лежащий в основе API openGL использует свою собственную систему от -1 до 1.

Самый простой способ добиться этого - функция glOrtho. Вот ссылка на документацию: http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml

Это пример правильного использования: glMatrixMode (GL_PROJECTION) glLoadIdentity (); глОрто (0, 800, 600, 0, 0, 1) glMatrixMode (GL_MODELVIEW)

Теперь вы можете использовать собственную матрицу modelView, т.е. для перевода (перемещения) объектов, но не трогайте пример проекции. Этот код должен выполняться перед любой командой рисования. (Может быть после инициализации opengl, если вы не будете использовать 3d графику).

А вот рабочий пример: http://nehe.gamedev.net/tutorial/2d_texture_font/18002/

Просто нарисуйте свои цифры вместо рисования текста. И есть еще одна вещь - glPushMatrix и glPopMatrix для выбранной матрицы (в этом примере матрица проекции) - вы не будете использовать это, пока не объедините 3d с 2d рендерингом.

И вы все еще можете использовать матрицу модели (т.е. для размещения плиток где-нибудь в мире) и матрицу вида (например, для масштабирования или прокрутки мира - в этом случае ваш мир может быть больше, чем разрешение, и вы можете обрезать вид простыми переводами)

Посмотрев на мой ответ, я вижу, что он немного хаотичен, но если вы запутались - просто прочитайте о моделях Model, View и Projection и попробуйте пример с glOrtho. Если вы все еще в замешательстве, не стесняйтесь спрашивать.

1 голос
/ 11 сентября 2011

MSDN имеет отличное объяснение . Это может быть с точки зрения DirectX, но OpenGL более-менее одинаков.

0 голосов
/ 11 сентября 2011

Google для "конвейера рендеринга opengl".Все первые пять статей дают хорошие экспозиции.

Переход от вершин к пикселям (на самом деле, фрагменты, но вы не будете слишком далеко, если вы думаете, что «пиксели») находится на стадии растеризации, котораяпроисходит после того, как все вершины были преобразованы из мировых координат в экранные координаты и обрезаны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...