Анимация текстур и рисование звонков производительность | OpenGLES 2.0 + Java - PullRequest
0 голосов
/ 15 мая 2018

Я создаю простую игру на Android Studio с использованием Java и OpenGL ES 2.0.

Если до сих пор я был обеспокоен более творческой стороной , то теперь я подошел к моменту, когда производительность начала играть важную роль, действительно во время тестирования на моем устройстве (Samsung Galaxy S8) Я начал замечать некоторое отставание или рассеяние.

Игра, как я сказал, довольно проста, она 2D, и на экране относительно мало объектов (15.10). Эти объекты движутся, поэтому есть базовый механизм обнаружения столкновений.

Я создал класс, который помогает мне отслеживать производительность и время выполнения функций (он создает строку, в которой указывается имя функции и время ее выполнения, затем я создал простую подпрограмму в Excel, которая сортирует их все в таблице. Любое предложение для отслеживания производительности в лучшем виде приветствуется). Из этих тестов я понял, что более медленные части моей игры - текстурная анимация и вызовы отрисовки .


Анимация текстур

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

Для достижения анимации я создаю одну большую текстуру и вставляю в нее кадров моей анимации. Я положил их в нижней части текстуры. Я создал Texture класс с методом void animate (int numbOfFrames, int animDuration), который я вызываю каждый раз, когда мне нужно нарисовать мой анимированный объект. Этот метод переключает координаты текстуры на основе истекшего времени. То, что делает этот метод медленным, я считаю тем, что он должен обновлять текстурные компоненты в VBO моего объекта каждый раз, когда он вызывается.

Я также пытался поместить кадры моей анимации в разные текстуры (один кадр = одна текстура), но мое приложение закончилось сбоем через несколько секунд. На самом деле, я думаю, что изменение текстуры и загрузка ее почти в каждом кадре очень дороги.

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


Розыгрыш звонков

Другая медленная часть моей игры - это ничьи.

Я структурировал свое приложение с разными классами для разных типов объектов. Например, я создал класс Cars для автомобилей, Planes для самолетов и так далее. Каждый объект каждого класса хранит свои собственные значения (например, его положение, его текстура, его скорость, его координаты, его матрица модели, его программа шейдера, ...). У каждого объекта есть метод для рисования.

Затем я создал класс для каждого типа объектов, который позаботился о их динамическом создании или удалении. Например, у меня есть Cars_Builder_, Planes_Builder_, ... Каждый Builder имеет ArrayList, который содержит объекты для рисования. Когда я вызываю xxxBuilder.draw(), он переходит в ArrayList и вызывает метод draw() каждого объекта.

Онлайн Я читал, что изменение состояний OpenGL стоит дорого. Поступая так, как я делаю, я меняю их много раз. Действительно, каждый вызов отрисовки должен выбирать правильную шейдерную программу, связывать данные (glVertexAttribPointer), вызывать glDrawArrays и другую связку изменяющих состояние вещей.

Так что я думаю об изменении реализации draw() в классе каждого вида объекта (Cars, Planes, ...). Я хочу поместить координаты каждого объекта каждого типа, который я должен нарисовать, в массив big , затем я вызываю реальный метод draw() через xxxBuilder. Таким образом, я значительно сокращаю количество дорогих вызовов (по одному для каждого типа объекта), но у меня есть несколько сомнений:

  • Мне нужно вычислить MVPmatrix * vertex на процессоре. Ведь каждая модель имеет свою позицию.
  • Даже если объекты одного типа похожи, они не идентичны, например, могут иметь разные текстуры. Но как я могу передать шейдерам разные textureID, если у меня один и тот же VBO, поэтому я рисую их одним и тем же вызовом glDrawArrays? Если есть способ фрагментировать вызов glDrawArrays, то мое первое сомнение будет решено: я бы передал разные формы (как текстуры, так и MVPmatrix) для каждого объекта.

Спасибо за чтение моих вопросов и извините, если мой английский не очень хорош, или я спросил / сказал очевидные вещи, или если он слишком широк.

...