Главная » Программирование игр под Android » ОБРАБОТКА ТЕКСТУР: ЛЕГКАЯ РАБОТА С ФОНОВЫМИ РИСУНКАМИ – РАЗРАБОТКА ИГР ДЛЯ ОС ANDROID

0

 

Когда мы писали Мистера Нома, мы загрузили ряд растровых изображений и напрямую отправили их в фреймбуфер – без поворотов, только слегка изменив масштабы, что было весьма несложно. В OpenGL ES нас в основном интересуют треугольники, которые могут иметь любую ориентацию и размер в зависимости от поставленной задачи. Как же визуализировать изображения с помощью OpenGL ES?

Все достаточно просто: загрузите изображения в OpenGL ES (точнее – передайте на обработку графическому процессору, который имеет свою выделенную RAM), добавьте новые свойства каждой вершине треугольника и прикажите OpenGL ES визуализировать наш треугольник и применить изображение (или текстуру, говоря на языке OpenGL ES) к нашему треугольнику. Рассмотрим сначала, что определяют эти новые свойства вершин.

Координаты текстур

Чтобы ассоциировать растровое изображение с треугольником, сначала нужно добавить к каждой вершине треугольника так называемые координаты текстур. Что же такое координата текстуры? Она определяет точку внутри текстуры (растрового изображения, которое мы загрузили), которая будет ассоциирована с одной из вершин треугольника. Координаты текстур, как правило, задаются для двух измерений.

Координаты месторасположения обозначают буквами х, у и z, а текстуры координат обычно называют и  v или s и t. В OpenGL ES их обозначают s и t, так что мы будем придерживаться этого названия. Если вы читаете какие-либо статьи в Интернете, которые используют названия u/v, не переживайте; это то же самое, что и s и t. Как же выглядит система координат? На рис. 7.10 показан Боб в текстурной системе координат после того, как мы загрузили его в OpenGL ES.

Здесь происходит несколько интересных вещей. Прежде всего, s равно координате х в стандартной системе координат, а г, в свою очередь, равно координате у. Ось s направлена вправо, а ось t – вниз. Начало системы координат совпадает с левым верхним углом изображения Боба. Нижний правый угол изображения имеет координаты (1; 1).

Что же случилось с пиксельной системой координат? Как оказалось, OpenGL ES не особо ее любит. Любое изображение, которое мы загружаем, вне зависимости от его ширины и высоты в пикселах, вставляется в данную систему координат. Верхний левый угол изображения всегда будет находиться в точке (0; 0), а нижний правый угол – в (1; 1), даже если его ширина в два раза больше высоты. Это называется нормализованными координатами. Они на самом деле иногда значительно облегчают нам жизнь. Так как же ассоциировать Боба с нашим треугольником? Все просто, мы присваиваем каждой вершине треугольника пару текстурных координат в координатной системе Боба. На рис. 7.11 показаны несколько конфигураций.

Рис. 7.10. Боб, загруженный в OpenGL ES и показанный в текстурной системе координат

Рис. 7.11. Три разных треугольника, нанесенных на Боба; координаты vi, v2 и v3 указывают вершины треугольника

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

Данные системы координат никак не связаны. Рассмотрим, как добавить эти координаты текстур к нашим вершинам:

Несложно, правда? Все, что нам осталось сделать, – убедиться, что у нас хватает места в буфере, а затем применить координаты текстур к каждой вершине. Предыдущий код соответствует самому правому варианту ассоциации, показанному на рис. 7.10. Обратите внимание, что положения наших вершин по-прежнему даются в обычной системе координат, которую мы описали с помощью проекции. При желании мы могли бы также добавить каждой вершине цветовые атрибуты, как в предыдущем примере. Затем OpenGL ES смешает интерполированные цвета вершин с цветами пикселов той текстуры, с которой ассоциируется треугольник. Это происходит динамически. Естественно, нам нужно настроить размер буфера, а также, соответственно, константы VERTEXSIZE (например, (2 + 4 + 2)  4)). Чтобы сообщить OpenGL ES, что у наших вершин есть текстурные координаты, мы снова используем методы gl Enabl eCl ientState и glTexCoordPointer, которые функционируют так же, как gl VertexPointer  и gl ColorPointer (видите закономерность?).

Отлично, все выглядит знакомым. Остается всего лишь один вопрос: как нам загрузить текстуры в OpenGL ES и указать ассоциировать их с треугольником? Естественно, это немного сложнее, однако тоже не составляет труда.

Загрузка растровых изображений

Для начала необходимо загрузить наше растровое изображение. Вы уже знаете, как это делается в Android:

Здесь мы загружаем Боба в конфигурации RGB888. Затем нам нужно сообщить OpenGL ES, что мы хотим создать новую текстуру. Чтобы создать объект текстуры, можно вызвать следующий метод:

Первый параметр определяет, как много объектов текстур мы хотим создать. Обычно создаем всего одну. Следующий параметр – это массив i nt, куда OpenGL ES будет записывать ID сгенерированных объектов текстур.

Последний параметр просто сообщает OpenGL ES, с какой точки массива нужно начинать записывать ID.

Вы уже знаете, что OpenGL ES – это API на языке С. Естественно, он не может вернуть нам Java-объект, соответствующий новой текстуре. Вместо этого он дает ID этой текстуры. Каждый раз, когда мы хотим, чтобы OpenGL ES что-то сделал с данной текстурой, мы указываем ее ID. Вот более сложный фрагмент кода, который демонстрирует, как сгенерировать новый текстурный объект и получить его ID:

Объект текстуры по-прежнему пуст. Это значит, что у него по-прежнему нет никаких графических данных. Загрузим наше растровое изображение. Для этого нам необходимо сначала привязать текстуру. В OpenGL ES под привязкой чего-либо понимается, что мы хотим, чтобы OpenGL ES использовал данный конкретный объект для всех последующих вызовов до тех пор, пока мы снова не изменим привязку. В данном случае мы хотим привязать текстуру объекта. Для этого мы используем метод gl BindTexture. Как только привяжем текстуру, сможем управлять ее свойствами, такими как данные об изображении. Вот как загрузить Боба в наш новый объект текстуры:

Сначала мы привязываем объект текстуры при помощи gl Bi ndTexture. Первый параметр определяет тип текстуры, которую мы хотим привязать. Наше изображение Боба – двухмерное, поэтому мы используем GL10. GL TEXTURE 2D. Существуют и другие типы текстур, но в этой е они нам не понадобятся. Мы всегда применяем GI 10.GL TEXTURE 2D для методов, которым необходима информация, с каким типом текстуры мы хотим работать. Второй параметр данного метода – ID текстуры. Когда метод выполнится, все последующие методы, которые работают с двухмерной текстурой, будут работать с нашим объектом текстуры.

При следующем вызове мы активируем метод класса GLUti Is, этот класс предоставляется во фреймворке Android. Обычно задача загрузки изображения текстуры достаточно сложна, однако этот небольшой вспомогательный класс значительно все облегчает. Все, что нужно сделать, – определить тип текстуры (GL10. GL TEXTURE  2D), уровень детализации (мы подробно рассмотрим его в главе 11, по умолчанию он равен нулю), изображение, которое мы хотим загрузить, и еще один аргумент, который должен быть равен нулю во всех случаях. После этого вызова к объекту текстуры будут прикреплены графические данные.

ПРИМЕЧАНИЕ

Объект текстуры и его графические данные фактически хранятся в видеопамяти, а не в обычной оперативной памяти. Объект текстуры (и графические данные) будут утеряны при потере контекста OpenGL ES (когда наша активность ставится на паузу, а затем возобновляется). Это значит, что надо будет заново воссоздавать объект текстуры и заново загружать графические данные каждый раз, когда создается контекст OpenGL ES. Если мы этого не сделаем, то увидим только белый треугольник.

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

По теме:

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