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

Как перевести отдельные объекты в OpenGL 3.x?

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

mat4 MVP;
gl_Position=MVP * gl_Vertex;

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

Ответ 2

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

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

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

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

Я надеюсь на помощь!