Рисование костей между вращающимися объектами

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

вертолет

Я рисую это в непосредственном режиме, по одной сетке за раз, и прохожу через стек пивотов, используя glRotate а также glTranslate, На этом рисунке разноцветные сетки нарисованы с правильными значениями сдвига и поворота - очевидно, одна или несколько операций все еще находятся в неправильном порядке.

Чтобы помочь отладить это, я подумал о том, чтобы нарисовать соединительную линию от центральной точки каждой сетки до той, к которой она должна подключиться. Тем не менее, это не представляется возможным в немедленном режиме!

Псевдо-код:

.. rotate/translate pivot #1
.. draw mesh #1 ..
glBegin (GL_LINES);
  glVertex3fv (center);
glEnd();
.. rotate/translate pivot #2
glBegin (GL_LINES);
  glVertex3fv (center);
glEnd();

не возможно, потому что GL_LINES работает только с парами вершин между ними, и вы не можете использовать glRotate а также glTranslate внутри glBegin а также glEnd,

Является единственно возможным решением для ручного вычисления матрицы поворота и перемещения для каждой отдельной точки, или же можно заставить OpenGL "запомнить" последнюю использованную вершину для использования со следующей GL_LINES команда?

1 ответ

Я не могу придумать, как применить различные преобразования к двум конечным точкам линии с фиксированным конвейером.

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

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

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

  2. Используйте массив униформ, которые содержат множество различных матриц преобразования. Тогда вы можете иметь атрибут вершины, который содержит индекс в этом массиве. Это позволяет вам выбирать из набора преобразований для каждой вершины.

  3. В простых случаях вы можете использовать вариант предыдущего подхода, но использовать предопределенный gl_VertexID переменная в вершинном шейдере для выбора преобразования.

Обратите внимание, что для всего этого не имеет значения, используете ли вы рисование в непосредственном режиме или если вы используете более современные методы рисования с VBO. Ограничение имеет фиксированный конвейер, где преобразования являются униформами, что означает, что они остаются постоянными для полной команды рисования.

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

Другие вопросы по тегам