Pyglet: эффективность с большими числами: обновление вершин по сравнению с матрицами opengl - PullRequest
0 голосов
/ 05 февраля 2020

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

В большинстве учебных пособий и обсуждений, которые я нашел в Интернете, рекомендуется использовать матрицы. У меня есть некоторый скептицизм, так как они фокусируются на небольшом количестве различных анимаций. Например, равномерное управление всей областью рендеринга или использование матриц push / pop для ~ 3 объектов. Я пытаюсь создать персональный интерфейс для симуляции рендеринга, и понятие 100+ объектов с индивидуальными особенностями анимации не является чем-то необычным.

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

Изображение моего двоичного дерева

Простое двоичное дерево уровня 10 содержит 2047 линейных сегментов , составляя 2047 списков вершин и 8188 координат вершин в 2D, 12282 в 3D. Я хочу оживить это, так, чтобы оно свернулось само по себе и снова. Я делаю это, меняя угол между двумя ветвями. Вот мой текущий подход (без inits et c):

class Branch(object):
    def update(self, parent_x, parent_y, change_angle_by):
        #calculate new vertices
        self.x0, self.y0 = parent_x, parent_y
        self.angle_change = change_angle_by
        self.angle += change_angle_by
        self.x1 = self.x0 + self.length * cos(self.angle)
        self.y1 = self.y0 + self.length * sin(self.angle)

        #update vertexlist vertices
        self.vertexlist.vertices = [self.x0, self.y0, self.x1, self.y1]

        #recurse
        if len(self.branches) > 0:
            self.branches[0].update(self.x1, self.y1, change_angle_by)
            self.branches[1].update(self.x1, self.y1, -change_angle_by)

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

Обратите внимание, как функция обновления действует как преобразование, используя конечные точки предыдущей ветви в качестве начальной точки следующей. Я также просто увеличиваю угол путем сложения, а не умножения матрицы. Влияние нового угла на вершины определяется через 1 косинус и 1 синус, а не 2 косинуса и 2 синуса, из которых состоит матрица вращения 2D. В целом, это кажется гораздо более эффективным в вычислительном отношении, чем могло бы быть использование матрицы. Чего мне не хватает, что делает умножение матриц более эффективным, чем копирование и сложение переменных?

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

class Branch(object):
    def update(self, change_angle_by):
        self.relative_angle += change_angle_by
        if len(self.branches) > 0:
            self.branches[0].update(change_angle_by)
            self.branches[1].update(-change_angle_by)

class BranchGroup(pyglet.graphics.Group):
     def __init__(self, parent_branch):
         self.parent = parent_branch
         pyglet.graphics.Group.__init__(self)

     def set_state(self):
         glPushMatrix()
         glTranslatef(self.parent.length, 0, 0)
         glRotatef(self.parent.relative_angle, 0, 0, 1)

     def unset_state(self):
         glPopMatrix()

Вспоминая мои уроки в колледже по линейной алгебре, умножение матриц должно быть намного дороже, чем то, что я делал. Матрицы вращения 2D имеют 2 синуса и 2 косинуса. Умножение двумерной матрицы вращения на двумерную матрицу перевода подразумевает 4 умножения строки-столбца, по 2 умножения и по 1 сложению каждое, суммирование до 2 косинусов, 2 синусов, 4 сложений и 8 умножений для каждой ветви. Не считая рекурсивных умножений. И 3D еще хуже. 9 умножений строк-столбцов по 3 умножения и 2 сложения в каждом, в идеале с использованием только 2 косинусов и синусов, но некардинальные матрицы вращения действительно очень дорого обойдутся.

Если бы кто-то мог указать мне ресурс на openGL Матрицы или яркий пример того, как их эффективно использовать, например, в этом двоичном дереве, мне было бы очень интересно. Спасибо, что прочитали это.

...