«

»

Апр
06

LibGDX. Рисуем 2d-кольцо со сглаживанием в Андроиде.

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

Рассуждаем

Так почему же кольцо нарисовать не просто? Во-первых, готовой функции ни в OpenGL, ни в LibGDX нет. Во-вторых, OpenGL ES не поддерживает GL_QUADS, которыми довольно просто можно аппроксимировать кольцо. Ну, а в-третьих, у нас нет сглаживания. Если на десктопе достаточно написать “сглаживание=true”, то на мобильных платформах так не получится – сглаживания просто нет. Поэтому нарисовать кольцо толстой линией тоже не получится, а нарисованный из треугольников круг будет с не очень красивыми краями.

Колец нам нужно рисовать много и размера они будут большого и толщина разная, поэтому простой вариант создать спрайтов на все случаи жизни отпадает, а жаль.

Делаем триангуляцию

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

схема аппроксимации круга

Кольцо представленное на рисунке выше состоит из 16-ти внешних (1, 3, 5, 7 и тд.) и 16-ти внутренних (2, 4, 6 и тд.) треугольников. Вывод такой структуры с использованием libGDX не представляет сложностей. Нужно лишь рассчитать массив координат всех вершин треугольников и вывести их с параметром GL_TRIANGLE_STRIP.

Для примера нарисуем кольца с разной степенью детализации. Зеленое сделаем из 8-ми, синее из 16-ти, а красное из 32-х внешних треугольников. Результаты данной операции представлены ниже.

аппроксимация круга треугольниками. зеленый - 8, красный - 16, синий - 32 внешних треугольника

Генерируем текстуру для сглаживания

Осталось добавить сглаживание. Наложим на кольцо текстуру, с полупрозрачными краями. Это позволит нам сымитировать сглаживание. К сожалению, чтобы сглаживание было качественным в широком диапазоне толщины круга, текстуру придется менять или генерировать новую на лету, но в моем случае круги приблизительно одинаковой толщины, поэтому я буду рассматривать случай с одной текстурой для всех толщин кругов, которую я создам только один раз. Так как каждый раз открывать фотошоп, чтобы нарисовать новую текстуру долго, мы будем генерировать текстуры для определенного диапазона толщины круга программно, с помощью Pixmap. Текстура наша будет содержать только alpha-канал (alpha only texture aka alpha mask) и не нести никакой информации о цвете. Ниже привожу код.

Комментарии. Мы создаем карту пикселей (Pixmap) размером 64х1 пиксель. Формат Pixmap.Format.Alpha говорит о том, что карта будет содержать информацию только о прозрачности (alpha канал) и не содержать информации о цвете. Основную часть карты делаем полностью непрозрачной (пиксели 4-27), а прозрачность крайних 4-х пикселей меняем от 0.1 до 0.9. Наложив такую текстуру на кольцо, позволит создать эффект сглаживания. Последняя строчка из карты пикселей, создает текстуру. Ниже привожу результат работы. Слева не сглаженное изображение, справа – сглаженное.

слева не сглаженное изображение, справа - сглаженное

Смотрим код

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

Пример использования класса в программе (более подробный пример будет скоро доступен на github).

Заключение

По-моему получилось очень хорошо. Со сглаживанием изображение стало намного приятнее, особенно, если в дальнейшем планируется делать анимацию. Данный алгоритм не ресурсоемкий и полностью автоматизирован (лазить в фотошоп для создания текстур не требуется). Буду рад услышать замечания и советы, libGDX я стал использовать совсем недавно и наверняка некоторые вещи сделал не так как следует.

П.С. В маркете можно посмотреть живые обои, которые использует описанный способ рисования.

6 комментариев

1 пинг

  1. desu Сообщает:

    Молодец, всё верно сделал!
    Спасибо за подсказку насчет Pixmap – не знал, что она может быть только альфа-каналом.

    1. PandaСoder Сообщает:

      изучение исходников открывает кучу всего интересного, документация по libgdx не отличается особой дружелюбность )

      1. Algoritmer Сообщает:

        Подскажите, где взять исходники libgdx? Скачал архив с оф. сайта, но там только jar – файлы

  2. Сергей Сообщает:

    Дружище, огромное спасибо! Такой код мне сейчас очень нужен.

    1. Сергей Сообщает:

      Жаль только, что привязка к OpenGL 1.0, но идея интересная.

  3. Jonathan Сообщает:

    Pleasing to find somoene who can think like that

  1. Canvas vs OpenGL/libGDX. Тестируем производительность на Андроид. » PandaCoder Сообщает:

    […] « LibGDX. Рисуем 2d-кольцо со сглаживанием в Андроиде. […]

Добавить комментарий

Мы сохраним Ваш e-mail в тайне.