2011-09-11 3 views
22

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

+1

Вершины FYI - это множественное число «вершин». В OpenGL координаты вершин умножаются на ряд матриц, чтобы получить конечный экран X, координату Y. –

+1

Хотя я знаю ответ на ваш вопрос, я тоже новичок в OpenGL, поэтому я не буду публиковать ответ, чтобы не сказать что-то не технически корректное. Что я сделаю, вам советуют прочитать OpenGL superbible. Это прояснит ситуацию для вас. Если вы не боитесь какой-либо математики, я бы рекомендовал [эту онлайн-книгу] (http://www.arcsynthesis.org/gltut/). –

+0

Это не попытка ответить, но, возможно, поможет прояснить ситуацию. Позиции вершин не имеют ничего общего с положениями пикселей, если у вас не будет настроен ваш viewport/transforms * just * right. Вершины живут в своем собственном пространстве. Например. если ваш лист бумаги 10x10, то насколько он большой? Подождите - 10x10 дюймов, сантиметров, футов, миль ...? –

ответ

26

Это довольно базовое знание о том, что ваш любимый учебный ресурс 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) вызова), которые являются вершиной»конечные позиции в буфере кадра и, следовательно, его координата пиксела.

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

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

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

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

EDIT: Не забудьте посмотреть на first link в ответ epatel, который объясняет трубопровод трансформации немного более практичный и точный.

-3

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

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

+5

Не ответ ... –

+0

@Armen: «Разве это можно объяснить кратко, или кто-нибудь может указать на статью или что-то, что объяснит это». Разве я не сделал этого? –

+1

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

11

Это называется преобразование.

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

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

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

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

+0

+1 Для первой ссылки, это намного более подробно и точно, чем мои объяснения. –

3

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

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

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

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

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

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

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

И здесь работает пример: http://nehe.gamedev.net/tutorial/2d_texture_font/18002/

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

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

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

1

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

+1

Но он, безусловно, путает новичков с нечетными вектор-матричными продуктами в отличие от векторных продуктов OpenGL. –

+0

Ну, действительно, действительно. Если вы сами реализуете матричный и векторный классы, то они оба идентичны;) – Goz

Смежные вопросы