Главная » Программирование игр под Android » Небольшое лирическое отступление о буфере NIO (нового ввода-вывода) – РАЗРАБОТКА ИГР ДЛЯ ОС ANDROID

0

Если быть абсолютно точным, нам необходимы прямые буферы NIO. Это значит, что их память находится не в куче виртуальной машины, а в нативной куче. Для создания прямого буфера NIO подойдет следующий фрагмент кода: ByteBuffer buffer = ByteBuffег.allocateDirect(NUMBER 0F BYTES): buffer. order(ByteOrder.nativeOrderO);

Здесь выделяется ByteBuffer, который может содержать NUMBEROFBYTES (общее количество байт) и проверяет, соответствует ли порядок байт используемому в центральном процессоре. Буфер NIO имеет три свойства: capacity – максимальное количество элементов, которое может содержать буфер; position – текущее местоположение, куда будет записан следующий элемент или откуда он будет прочтен; 1imit – индекс последнего определенного элемента плюс один.

Фактически вместимость буфера – это его размер. В случае ByteBuffer этот размер измеряется в байтах. Свойства position и limit можно считать определяющими сегмент внутри буфера, который начинается с position и заканчивается на limit (исключающе).

Поскольку мы хотим определить наши вершины как числа с плавающей точкой, хорошо бы справиться с этими байтами. К счастью, мы можем преобразовать экземпляр класса ByteBuffer в экземпляр класса FloatBuffer, который позволяет нам работать с числами с плавающей точкой.

В случае с FloatBuffег свойства capacity, position и 1imit являются числами с плавающей точкой. Наш паттерн использования данных буферов достаточно прост. Он выглядит следующим образом:

Сначала определяем наши данные в стандартном массиве Java из чисел с плавающей точкой. Перед тем как вставить массив в буфер, указываем буферу очистить себя с помощью метода clear О. Фактически так не стираются никакие данные, просто, position получает значение 0, а 1imit становится равным capacity. Далее используем метод FloatBuffer .put float  array), чтобы скопировать содержимое всего массива в буфер, начиная с текущей позиции в буфере. После копирования эта позиция увеличится на длину массива. Далее вызываем метод put, который добавляет дополнительные данные к данным предыдущего массива, который мы скопировали в буфер. Последний вызов FloatBuffer. f1ip просто меняет местами capacity и 1imit.

Чтобы лучше понять, как это работает, предположим, что наш массив вершин имеет размер в 5 чисел с плавающей точкой и что capacity нашего FloatBuffer достаточно велика, чтобы вместить в себя эти 5 чисел. После вызова FloatBuffer. put  позиция буфера будет равна 5 (индексы от 0 до 4 заняты 5 числами с плавающей точкой из нашего массива), 1imit по-прежнему будет равен вместимости буфера. После вызова FloatBuffer. fl ip свойству position будет задано значение 0, a limit будет установлен в 5. Любая сторона, которая попробует прочесть данные из буфера, будет знать, что ей следует читать числа с плавающей точкой из индекса 0-4 (включительно). Об этом необходимо знать и OpenGL ES. Обратите внимание, что OpenGL ES тем не менее не учитывает limit. Обычно мы сообщаем количество элементов, которое необходимо прочесть, делаем это вместе с передачей буфера. На данном этапе не проверяются ошибки, так что будьте внимательны.

Иногда лучше установить position буфера вручную после того, как мы его заполнили. Это можно сделать с помощью следующего метода:

Это пригодится нам позже, когда мы временно установим свойству position заполненного буфера какое-либо значение, отличное от нуля, для того чтобы OpenGL ES начал считывание данных буфера с конкретного адреса.

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

По теме:

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