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

0

 

В предыдущем примере мы установили глобальный цвет но умолчанию для всех вершин, которые мы рисуем с помощью gl Col or4f . Иногда нам требуется более тонкий контроль (например, возможность устанавливать цвет для каждой из вершин). OpenGL ES предлагает нам данный функционал, который по-настоящему легок в использовании. Все, что нам надо сделать, – добавить float-компоненты RGB А к каждой вершине и сообщить OpenGL ES, где можно найти цвет для всех вершин так же, как мы сообщали, где можно найти расположение каждой вершины.   Начнем с того, что присвоим цвет каждой вершине:

Сначала необходимо выделить ByteBuffer для наших трех вершин. Какой размер должен иметь этот ByteBuffer? У нас есть две координаты и четыре (RGBA) компонента цвета для каждой вершины, что в сумме составляет 6 чисел с плавающей точкой. Каждое значение float занимает 4 байта, так что каждая вершина требует 24 байта. Мы сохраняем данную информацию в VERTEXSIZE. Когда мы вызываем ByteBuffer.allocateDirect, мы просто умножаем VERTEX SIZE на количество вершин, которое хотим сохранить в ByteBuffer. Оставшаяся часть понятна сама по себе. Мы получаем вид Fl oatBuf fer для нашего ByteBuffer и помещаем вершины методом put в ByteBuffer. Каждый ряд массива float содержит х- и г/-координаты, а также R-, G-, В- и А-компоненты вершины именно в таком порядке.

Если мы хотим визуализировать это, нам необходимо сообщить OpenGL ES, что наши вершины не только имеют местоположение, но также и свойство цвета. Мы это делаем так же, как и раньше, с помощью вызова gl Enabled ientState:

Теперь, когда OpenGL ES известно, что можно ожидать информацию о положении и цвете для каждой из вершин, мы сообщаем, где можно получить эту информацию:

Мы начинаем с установки положения нашего FloatBuffer. Позиция указывает нах-координату нашей первой вершины в буфере. Далее вызываем gl VertexPointer.

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

Далее мы устанавливаем местоположение буфера для компонента R нашей первой вершины и вызываем glColorPointerO, который сообщает OpenGL ES, где можно найти цвета вершин. Первый аргумент – это количество компонентов на цвет. Он всегда равен четырем, поскольку OpenGL ES требует от нас компоненты R, G, В и А для каждой вершины. Второй параметр описывает тип каждого компонента. Как и с координатами вершин, мы снова используем GL10.GL FLOAT для указания, что каждый цветовой компонент является числом с плавающей точкой в диапазоне от 0 до 1. Третий параметр – это интервал между цветами вершин. Он, естественно, равен интервалу между местоположениями вершин. Последний параметр – это снова наш буфер вершин.

Поскольку мы вызвали vertices .position(2) перед gl Col orPoi nter, OpenGL ES знает, что данные цвета первой вершины можно найти, начиная с третьего числа float в буфере. Если бы мы не указали, что местоположение буфера равно 2, OpenGL ES начал бы читать цвета с 0. Это было бы не очень хорошо, поскольку сначала у нас идут х-координаты нашей первой вершины.

Рисунок 7.8 демонстрирует, откуда OpenGL ES будет читать свойства вершин и как он перескакивает от одной вершины к другой для каждого из свойств.

Чтобы нарисовать наш треугольник, мы снова вызываем gl DrawEl ements , который приказывает OpenGL ES нарисовать треугольник, используя первые три вершины нашего FloatBuffer:

Поскольку мы использовали константы GL10. GL VERTEX ARRAY и GL10. GL C0L0R ARRAY, OpenGL ES знает, что он должен применять свойства, определенные gl VertexPointer  и gl ColorPointer . Он будет игнорировать цвет, заданный по умолчанию, поскольку мы указываем отдельный цвет для каждой вершины.

Рис. 7.8. FloatBuffer вершин, начальные адреса для OpenGL ES, чтобы прочесть местоположение/цвет, и шаг, используемый для перехода к следующему местоположению/цвету

ПРИМЕЧАНИЕ

То, как мы только что описали местоположение наших вершин, называется чередованием (interleaving). Это значит, что мы записываем все свойства вершин в один блок памяти. Достичь такого эффекта также можно, воспользовавшись массивами не чередующихся вершин (noninterleaved vertex arrays). Мы можем использовать два FloatBuffer: один для указания местоположения, другой для цвета. Тем не менее чередование гораздо удобнее применять с точки зрения экономии памяти, так что мы не будем здесь обсуждать массивы не чередующихся вершин.

Соединение всего вместе в новой реализации GLGame и Screen должно теперь показаться совсем простым. В листинге 7.6 показан фрагмент из файла Col oredTri angl eTest. Java. Я опустил шаблонный код.

Листинг 7.6. Отрывок из ColoredTriangleTest.Java; Чередование свойств местоположения и цвета

Здорово, получилось вполне незамысловато. Все, Что мы изменили по сравнению с предыдущим примером, – добавили в наш Fl oatBuf fer четыре компонента цвета для каждой из вершин и использовали GL10  GLC0L0RARRAY. Лучше всего в данных изменениях то, что любые дополнительные свойства, которые мы будем приписывать нашим вершинам позже, будут работать ровно таким же образом. Мы просто указываем OpenGL ES не использовать значения, заданные по умолчанию для данного свойства, а вместо этого брать свойства в нашем FloatBuf fer, начиная с определенного адреса и передвигаясь от вершины к вершине по байтам VERTEX SIZE.

Теперь мы можем также выключить GL10. GLC0L0RARRAY, чтобы OpenGL ES мог снова использовать цвет по умолчанию, который мы определили с помощью glColor4f, как это делалось раньше. Для этого мы вызываем: gl.glDisableCli entState(GL10.GL C0L0R ARRAY):

OpenGL ES просто выключит свойство чтения цвета из нашего FloatBuf fer. Если мы уже установили указатель цвета с помощью glColorPointerO, OpenGL ES запомнит указатель, однако мы только что приказали ему его не использовать.

Чтобы подвести итоги, рассмотрим вывод предыдущей программы (рис. 7.9).

Рис. 7.9. Треугольник, где цвет каждой вершины описан отдельно

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

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

По теме:

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