Подтвердить что ты не робот

OpenGL определяет положение вершин в пикселях

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

Главное, чтобы помнить, что после преобразования модели и проекции каждая вершина с координатами вне диапазона [-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.

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

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

Ответ 2

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

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

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

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

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

Ответ 3

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

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

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

И вот трюк вам понадобится. Вы должны прочитать о матрице 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)

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

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

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

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

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

Ответ 4

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

Ответ 5

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

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