Я создаю простую игру на 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) для каждого объекта.
Спасибо за чтение моих вопросов и извините, если мой английский не очень хорош, или я спросил / сказал очевидные вещи, или если он слишком широк.