glMultMatrix / glLoadMatrix более эффективен, чем glRotatef или glTranslatef? - PullRequest
3 голосов
/ 23 декабря 2011

Предположим, у меня есть следующий код:

glRotatef(angle, 1.0f, 1.0f, 0.0f);
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glTranslatef(0.0f, 0.0f -5.0f);

Является ли это менее эффективным, чем использование собственной пользовательской матрицы через функцию glLoadMatrix, которая выполняет те же функции?

Кроме того, я знаю, что при умножении матриц для формирования произвольного линейного преобразования последняя умноженная матрица является первым преобразованием, которое должно иметь место. Аналогично, так ли это, если я использую приведенный выше код? Будет ли он перемещаться, затем вращаться вокруг оси Z, а затем вращаться вокруг осей Y и X?

Ответы [ 4 ]

7 голосов
/ 23 декабря 2011

В общем, если вы собираете свою матрицу самостоятельно и загружаете ее через glLoadMatrix или glMultMatrix, ваша программа будет работать быстрее.Если вы не допускаете глупых ошибок в своих собственных матричных подпрограммах, которые, конечно, ухудшают производительность.

Это потому, что функции glRotate glTranslate и т. Д. Делают немного больше, чем чистая математика.Они должны проверить матричный режим.glRotate имеет дело со случаями, когда ось не передается как единичный вектор и т. д.

Но если вы не сделаете это 10 тысяч раз за кадр, я не буду беспокоиться о потерянной производительности.Это добавляет, но это не так уж много.

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

Нет необходимости говорить, что код, написанный с таким подходом, также легче портировать на другой графический API (подумайтеOpenGL | ES2, DirectX, игровые приставки ...)

3 голосов
/ 23 декабря 2011

Согласно спецификациям OpenGL, glRotate и glTranslate используют свои параметры для создания матрицы 4x4, тогда текущая матрица умножается на произведенную матрицу (glRotate или glTranslate) с продуктом, заменяющим текущую матрицу.

Это примерно означает, что в вашем зачисленном коде у вас есть 4 умножения матриц!Кроме того, у вас есть 4 вызова API и несколько других вычислений, которые преобразуют углы glRotate в матрицу 4x4.

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

2 голосов
/ 23 декабря 2011

Является ли это менее эффективным, чем использование собственной пользовательской матрицы через функцию glLoadMatrix, которая выполняет те же функции?

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

Примером очень плохого программирования было что-то вроде этого (псевдокод):

glMatrixMode(GL_MODELVIEW)
for q in quads:
    glPushMatrix()
    glTranslatef(q.x, q.y, q.z)
    glBindTexture(GL_TEXTURE_2D, q.texture)
    glBegin(GL_QUADS)
    for v in [(0,0), (1,0), (1,1), (0,1)]:
        glVertex2f(v[0], v[1]
    glEnd()
    glPopMatrix()

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

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

1 голос
/ 23 декабря 2011

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

С другой стороны, в «новой» версии OpenGL все эти функции отсутствуюти помечены как устаревшие.Таким образом, в новом стандарте вы вынуждены использовать пользовательские математические функции (при условии, что вы используете профиль Core)

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