Главная » Программирование игр под Android » Обходной маневр при помощи FloatBuffer – РАЗРАБОТКА ИГР ДЛЯ ОС ANDROID

0

Причина этого совсем не очевидна. Наш SpriteBatcher помещает массив переменных float в прямой ByteBuffer каждый кадр, когда мы вызываем Vertices. setVertices. Метод сводится к вызову FloatBuffer.put (f1oat), и именно он виновен в ухудшении производительности. В то время как настольная версия Java выполняет метод Fl oatBuf fer, задействовав память большого объема, версия Harmony вызывает FloatBuffer.put для каждого элемента массива. И это очень плохо, потому что этот метод является JNI-методом, который приводит к большим издержкам (как и методы OpenGL ES, которые также представляют собой JNI-методы).

Есть несколько решений проблемы. Например, IntBuffer.put(int) этой проблеме не подвержен. Мы можем заменить FloatBuffer в нашем классе Vertices на IntBuf fer и изменить Verti ces. setVerti ces  так, чтобы он сначала переносил переменные float из float-массива во временный int-массив и затем копировал содержимое этого int-массива в IntBuf fer. Это решение предложил разработчик игр Райан МакНелли, котрый также сообщил о баге в багтрекер Android. При устранении этого бага производительность на Него увеличится в пять раз и немного меньше на других устройствах с Android.

Я включил в класс Verti ces это изменение. Для этого я изменил тип поля verti cies на IntBuf fer. Я также добавил новый член tmpBuffer, который является массивом чисел int. Массив tmpBuffer инициализируется в конструкторе Vertices следующим образом:

Мы также можем увидеть IntBuf fer в конструкторе вместо FloatBuffer из ByteBuffer:

А метод Verti ces. set Verti cesО выглядит вот так:

Таким образом, все, что мы делаем, – переносим содержимое параметра вершин в tmpBuffer. Статический метод Float.floatToRawIntBitsO заново интерпретирует конфигурацию битов f1oat как i nt. Нам нужно только скопировать содержимое массива i nt в IntBuf fer, ранее известный нам как Fl oatBuf fer. Увеличит ли это производительность? Теперь при использовании Spri teBatcherTest на Hero, Droid и Nexus One мы получаем такие результаты:

Да, я перепроверил, это не опечатка. Кадровая частота на Него теперь действительно 60 кадров в секунду. Обходной маневр размером всего в пять строк кода увеличивает быстродействие на 50 %. Быстродействие Droid тоже немного возрастает.

ПРИМЕЧАНИЕ

Есть еще и другой, более быстрый способ обойти проблему. Он касается JNI-метода, который производит изменения в памяти собственного кода. Вы можете найти его в Интернете в Android Game Development Wiki. Я по большей части использую этот обходной путь вместо чистого Java-способа. Однако работа с JNI-методами немного более сложная, поэтому я описал здесь способ решения с помощью Java.

Источник: Mario Zechner / Марио Цехнер, «Программирование игр под Android», пер. Егор Сидорович, Евгений Зазноба, Издательство «Питер»

По теме:

  • Комментарии