Pull to refresh

Андроиды в дельфинарии

Delphi *Game development *Development for Android *Development for Windows *
Приветствую всех любителей тех устройств, что помещаются в карман, а также тех, кто держит свой карман шире 7". Сейчас мы займемся искусством программирования кросс-платформенных графических приложений, то есть таких приложений, которые работают на мобильной платформе (смартфоны и планшеты Android) и под Windows (стационарные PC, ноутбуки, нетбуки, планшеты). При этом наши приложения будут графическими, графика основана на OpenGL (OGL) и его мобильном варианте OpenGL ES (GLES). Я использую Embarcadero Delphi XE7. Важная особенность – в этом проекте я не использую платформу FM (FireMonkey), мы будем писать все сами и с нуля, как в старые добрые времена.

image

Предлагаю сразу разделить работу пополам:
— я пишу кросс-платформенную графическую библиотеку, рассматриваю примеры её использования, расписываю детали реализации, отвечаю на вопросы;
— ваша часть не менее ответственна: от вас мне нужен тест демок на различных мобильных устройствах, рапорты о выполнении, отзывы и критика, новые идеи и свежее мясо новые пользователи как библиотеки так и собственно приложений.

1. Первая демка
Android mc.apk 3.8 MB yadi.sk/d/n1wDuX1RhC4QX
Windows mc.zip 1.9 MB yadi.sk/d/tBKQxaV7ff8KW
Исходные тексты в репо: sourceforge.net/p/delphioga/code/ci/default/tree
В первой версии программа не хитрая – она просто выводит на экран 4096 угловатых разноцветных шариков и позволяет полетать мимо них в режиме “свободной камеры”. Сферы я раскрасила по принципу цветового пространства RGB, ещё они вращаются. На этом примере я хочу рассмотреть методы построения 3D примитивов (в частности сфер) и приёмы оптимизации отрисовки (Frustum сulling, детализация объектов).
Но нам никак не обойтись без небольшой вводной части.

2. Инструкция по эксплуатации, смартфон/планшет Android
1. Устанавливаем mc.apk, это архив инсталляции программы. Если у вас есть вопросы как это сделать, я готова помочь.
2. При установке apk возможно предупреждение, что программа требует доступа к Internet. На самом деле программа скомпилирована в режиме Debug, поэтому ей потенциально нужен доступ к локальной сети для возможности работы отладчика (gdbserver) и консоли логов logcat. Логи нам еще потребуются. Из самой программы к сети я не обращаюсь никак, там есть только рисование графики на экране.
3. После установки у вас добавится новый ярлычок на Рабочем столе “mc”. Запускаем программу. Любуемся на заставку — огонек FM (я пока не меняла иконки мобильного проекта Delphi по умолчанию). Обращаем внимание на время запуска приложения, сколько оно у вас приблизительно в секундах и их долях? Мы можем сравнить это с временем загрузки примеров FM приложений, пока что сравнение в нашу пользу.
4. Вот вы и на месте, добро пожаловать. Используйте ваши пальцы и тачскрин для изменения направления взгляда и направления движения. Справа вверху есть парочка экранных кнопок – вперед и назад. Если у вас 2 руки, вы можете одновременно двигаться и поворачиваться. Для этого потребуется определенная сноровка, уж чего-чего, а простой жизни я не обещала.
5. При переключении в другое приложение или “засыпании” планшета (давайте мобильное устройство именовать планшетом, потому что у меня планшет) программа приостановит отрисовку графики (контекст GLES и само окно приложения удаляются, так положено делать на Android), однако сама программа не прекратит работу. При переключении обратно в приложение или “пробуждении” планшета окно и контекст будут созданы заново, мы продолжим наше путешествие с места остановки. Следует обращать внимание на этот нюанс при тестировании, некоторые игры не умеют корректно “восстанавливаться”, мы же должны уметь.
6. Поверните планшет горизонтально, потом вертикально. Работу приложения следует проверять в каждом из этих двух режимов. Разумеется такой фокус сработает, только если у вас ориентация дисплея устройства установлена в “авто”.
7. Выйти из демки просто – нажмите системную кнопку “назад”.
8. Напишите в комментариях к статье тип мобильного устройства, которое вы применяли (фирма-производитель, модель), я постараюсь отыскать его характеристики, типы CPU и GPU, версию OS. Эти данные я включаю в файл hardware.txt в репо.

image

3. Инструкция по эксплуатации, Windows
1. Распаковываем архив zip. Не удивляемся объему exe файла, демка скомпилирована в режиме Debug, в релизе exe весит 1.5 MB. Запускаем mc.exe.
Никаких системных предупреждений о использовании сети, как в Android не будет, потому что сеть в демке не используется, на PC отладчик и логи работают локально.
2. Вот вы и на месте, добро пожаловать. Для изменения направления взгляда и направления движения “потащите” экран при нажатой левой кнопке мышки (ЛКМ). Для перемещения в пространстве работают клавиши [WASD] на клавиатуре (либо стрелки, либо стрелки на NumPad). Экранные кнопки для движения вперед-назад тоже есть, они кликабельны. [F1] выводит справку, [ESC] позволяет выйти из программы.
3. Обратите внимание на второе окно (при запуске программы на панели управления появляется два окна), это консоль отладки. Подобную консоль для Android (logcat) мы рассмотрим позже. После GPU Vendor, Renderer (фирма/тип вашей видеокарты) там пишет Open GL version. Скажем так, если версия OpenGL ниже 3.0, то некоторые будущие возможности библиотеки не пойдут на вашей старой видеокарте. Впрочем, прикладное приложение может содержать 2 ветки реализации таких возможностей и работать в любом случае.
4. VSYNC в этом примере выключен, FPS может быть куда больше 60 Гц (попробуйте отвернуться от видимых объектов), нагрузка на GPU и CPU максимальна. Я так делаю для тестирования скорости отрисовки фрейма, если включить VSYNC нагрузка станет нормальной.

4. Отладочный вывод на экран
На скриншотах слева вверху есть некоторые желтые буквы и цифры.
FPS – среднее число кадров в секунду, наш главный инструмент в оценке быстродействия рисования. Под Android VSYNC включен, FPS лимитирован частотой обновления экрана (60 Гц), впрочем я так подогнала нагрузку на GPU в демо, что на большинстве мобильных устройств FPS будет “проседать”. Это не страшно пока управление и анимация остаются адекватными. Под Windows же VSYNC выключен, FPS не имеет лимита;
TDF – среднее время отрисовки одного фрейма в миллисекундах, по сути величина обратная FPS; она нужна чтобы понимать “тайминг” — какого порядка интервалы времени у нас фигурируют для рисования кадра; при FPS 60 Гц это время около 17 мс;
NFR – число отрисованных фреймов от старта приложения; при FPS 60 Гц в первую же секунду эта цифра достигнет 60;
T – время в мс от старта приложения, его я использую как аргумент для функций анимации, в примере от него зависит вращение сфер;
POS — координаты камеры в 3D мире XYZ, при старте оси расположены так: X направо, Y вверх, Z на нас;
AH, AV — углы поворота камеры относительно горизонтали и вертикали в градусах; об угле крена лучше поговорить отдельно;
N – общее число объектов во Вселенной;
NV – столько объектов целиком или частично попадают в область видимости (фрустум, усеченная пирамида поля зрения камеры);
HD – столько ближних объектов отображаются с несколько лучшим качеством отрисовки, дальние объекты рисуются попроще;
SCR — разрешение экрана.

5. Как выглядит процесс разработки
Я подключаю планшет к PC под Windows USB-кабелем (можно и через Wi-Fi). Сначала пишу платформенно-зависимый код неких функций для Android, запускаю программу на планшете. Эта часть работы требует много терпения, приложение сравнительно долго компилируется и запускается на планшете. Отладка доступна (точки остановки, пошаговое выполнение, просмотр состояния переменных). Также использую отладочный вывод приложения в logcat, смотреть логи могу прямо на PC в реальном времени. Когда на планшете заработало, я пишу платформенно-зависимый вариант кода функций для Windows, это уже проще. После этого начинается самое интересное – основную часть программы я пишу универсальным кодом вызывая одноименные платформенные функции, проверяю на PC и лишь изредка заливаю на планшет, как правило, там все работает.

6. Под капотом
Заглянем немного в исходные тексты. В папке common у меня лежит собственно библиотека. Начнем с файла Draw.pas.
На чем основана кросс-платформенная графика? Под Windows я использую модуль OpenGL.pas, но только те функции, которые имеют аналоги в GLES под Android (модули Androidapi.Egl.pas, Androidapi.Gles.pas, Androidapi.Gles2.pas).
uses
  Types,SysUtils,
{$IFDEF Android}
  Androidapi.Egl, Androidapi.Gles, Androidapi.Gles2,
{$ENDIF}
{$IFDEF MSWINDOWS}
  Winapi.OpenGL,
{$ENDIF}
  Vectors, Colors, Textures, DrawPolyhedron, DrawSphere;

Там где OGL и GLES совпадают разницы в синтаксисе мало, вот разве что glOrtho пришлось подровнять. При помощи директив условной компиляции типа {$IFDEF ANDROID} и {$IFDEF MSWINDOWS} мы будем описывать платформенно-зависимую реализацию.
{$IFDEF ANDROID}
procedure glOrtho (left, right, bottom, top, zNear, zFar: GLfloat);
begin
  glOrthof(left, right, bottom, top, zNear, zFar);
end;
{$ENDIF} 

Что ещё не совпадает? На GLES нет glBegin/glEnd и соответственно всего связанного с ними семейства функций. Это не страшно, будем рисовать в стиле OGL 2.0 передавая за один раз указатели на массивы вершин (нормалей, цветов, текстурных координат). Например, один простейший треугольник можно нарисовать так (цвет текущий, нормалей и текстур нет):
procedure Triangle(p1, p2, p3: TV3); overload;
begin
  SetLength(ap3, 3);
  ap3[0] := p1;
  ap3[1] := p2;
  ap3[2] := p3;
  glVertexPointer(3, GL_FLOAT, 0, @ap3[0]);
  glDrawArrays(GL_TRIANGLES, 0, Length(ap3));
end;

Чтобы нарисовать множество треугольников 3D фигуры не следует вызывать процедуру Triangle много раз. Следует сложить все вершины всех треугольников в один массив и нарисовать их единственным вызовом glDrawArrays. Эта функция используется в текущем демо для рисования каждой сферы, как с GL_TRIANGLES так и с GL_TRIANGLE_STRIP:
// отобразить готовый массив вершин c нормалями 
procedure DrawAVNT(avn: TAVertexN; met:GLenum; Position,Rotation,Scale: TV3);
begin
 glPushMatrix;
 Transform(Position,Rotation,Scale);
 glVertexPointer(3, GL_FLOAT, SizeOf(TVertexN), @avn[0].V);
 glNormalPointer(GL_FLOAT, SizeOf(TVertexN), @avn[0].N);
 glDrawArrays(met,0,Length(avn));// GL_TRIANGLES
 glPopMatrix;
end;


На этом мы прервемся, для первого знакомства такой вводной части должно хватить. Если понравится — у меня уже есть наброски продолжения статьи.

PS/05.06.2015
В библиотеку добавлена загрузка 3D моделей в формате obj.

image

Дополнительный источник информации по теме: forum.sources.ru/index.php?showtopic=401121
Tags:
Hubs:
Total votes 22: ↑16 and ↓6 +10
Views 12K
Comments Comments 28