Как мне перевести отдельные объекты в OpenGL 3.x? - PullRequest
16 голосов
/ 28 октября 2009

У меня есть небольшой опыт написания приложений для OpenGL 2, и я хочу научиться использовать OpenGL 3. Для этого я купил "Red-book" и "Orange-book" (GLSL) Addison Wesley, которые описывают устаревание исправлена ​​функциональность и новый программируемый конвейер (шейдеры). Но я не могу понять, как построить сцену из нескольких объектов, не используя устаревшие функции translate *, rotate * и scale *.

В OGL2 я обычно «перемещался» в трехмерном пространстве, используя функции перевода и поворота, и создавал объекты в локальных координатах, где я хотел, используя glBegin ... glEnd. В OGL3 все эти функции устарели и, как я понимаю, заменены шейдерами. Но я не могу вызвать шейдерную программу для каждого объекта, который я делаю, не так ли? Разве это не повлияет и на все остальные объекты?

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

Редактировать: представьте, что вы хотите два вращающихся кубика. Было бы трудно вручную изменить каждую координату вершины, и вы не можете просто изменить матрицу просмотра модели, потому что это скорее повернет камеру вокруг двух статических кубов ...

Ответы [ 2 ]

20 голосов
/ 28 октября 2009

Давайте начнем с основ.

Обычно вы хотите преобразовать свои локальные вершины треугольника с помощью следующих шагов:

local-space coords-> world-space coords -> view-space coords -> clip-space coords

В стандартном GL первые 2 преобразования выполняются через GL_MODELVIEW_MATRIX, третье - через GL_PROJECTION_MATRIX

Эти преобразования вида модели для многих интересных преобразований, которые мы обычно хотим применить (например, преобразовать, масштабировать и повернуть), оказываются выразимыми как векторно-матричное умножение, когда мы представляем вершины в однородные координаты . Как правило, вершина V = (x, y, z) представлена ​​в этой системе как (x, y, z, 1).

Ok. Скажем, мы хотим преобразовать вершину V_local посредством перевода, затем вращения, а затем перевода. Каждое преобразование может быть представлено в виде матрицы *, назовем их T1, R1, T2. Мы хотим применить преобразование к каждой вершине: V_view = V_local * T1 * R1 * T2. Матричное умножение, будучи ассоциативным, мы можем вычислить раз и навсегда M = T1 * R1 * T2.

Таким образом, нам нужно только передать M вершинной программе и вычислить V_view = V_local * M. В конце типичный вершинный шейдер умножает положение вершины на одну матрицу. Вся работа по вычислению этой матрицы состоит в том, как вы перемещаете свой объект из локального пространства в пространство клипа.

Хорошо ... Я просмотрел ряд важных деталей.

Во-первых, то, что я до сих пор описывал, действительно охватывает только те преобразования, которые мы обычно хотим выполнять, до пространства просмотра, а не пространства клипа. Однако аппаратное обеспечение ожидает, что выходная позиция вершинного шейдера будет представлена ​​в этом специальном пространстве клипа. Трудно объяснить координаты пространства клипа без значительной математики, поэтому я опущу это, но важный момент заключается в том, что преобразование, которое приводит вершины в это пространство клипа, обычно может быть выражено как тот же тип умножения матриц. Это то, что вычисляют старые gluPerspective, glFrustum и glOrtho.

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

В-третьих, вы никогда не отправляете 4-D координаты в вершинный шейдер. В общем, вы проходите 3-D. OpenGL преобразует эти 3-D координаты (или 2-D, кстати) в 4-D, так что вершинному шейдеру не нужно добавлять дополнительную координату. он расширяет каждую вершину, чтобы добавить 1 в качестве w координаты.

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

mat4 MVP;
gl_Position=MVP * gl_Vertex;

* фактические матрицы можно найти в Интернете, особенно на страницах руководства для каждой из этих функций: поворот , перевод , масштаб , перспектива , орто

1 голос
/ 28 октября 2009

Эти функции, по-видимому, устарели, но технически все еще отлично функционируют и действительно будут компилироваться. Таким образом, вы все еще можете использовать функции translate3f (...) и т. Д.

ОДНАКО, этот урок содержит хорошее объяснение того, как работают новые шейдеры и т. Д. И для нескольких объектов в пространстве.

Вы можете создавать x массивов вершин и связывать их с x объектами VAO, и вы визуализируете сцену оттуда с помощью шейдеров и т. Д. Мех, вам проще просто прочитать это - это действительно хорошее чтение для понять новые концепции.

Кроме того, в «Красной книге» OpenGL есть новая версия - Официальное руководство по изучению OpenGL, версии 3.0 и 3.1 . Он включает в себя «Обсуждение механизма устаревания OpenGL и как проверить ваши программы для будущих версий OpenGL».

Надеюсь, это поможет!

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