Программируем трехмерную графику с Irrlicht . Часть 1

August 1, 2007

Эффективное программирование 3d-приложений с помощью Irrlicht и jython. Часть 1.



Эта статья начнет серию материалов посвященных разработке 3d-приложений. Будут рассмотрены общие методики проектирования и программирования, которые могут быть применены как для разработки игр, так и для разработки более серьезных приложений: например задач визуализации каких-либо физических или химических процессов, создания моделей интерьера, или графического изображения поверхностей задаваемых некоторыми математическими функциями, в общем всего что будет подвластно вашей фантазии.

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

Мой подбор их - конечно не единственный и если вы пообщаетесь с людьми, профессионально занимающимися определенными выше задачами они приведут в качестве оснований для выбора совершенно другие характеристики, которыми должны обладать эти средства и будут совершенно правы. Как говорится “нет серебряной пули” – или, проще говоря, нет такого волшебного средства (инструмента, технологии), которое идеально подходило бы всегда и всем.

Предположим, что мы хотим начать с задачи разработки простой 3d игрушки а-ля пинг-понг. Чем проще задача с которой вы начинаете изучение новой технологии, тем вам проще будет ее довести до стадии "ух-ты, работает", не погрязнув при этом во множестве мелочей, багов, фич и непредвиденных затрат во времени. Как известно в программировании, как и везде, действует правило “20 на 80”, согласно которому вам для того, чтобы сделать 80 процентов проекта, необходимо затратить 20 процентов распланированного времени, а на оставшиеся 20 процентов как раз и уйдут все 80, и даже больше.

Правило это не действует только в очень редких ситуациях. А, кроме того мелочи зачастую и определяют отношение к программному продукту в целом. Как не был хорош разработанный вами проект, но если в нем для выполнения некоторой типовой функции – скажем, сохранения документа, необходимо выполнить 50 кликов мышью, то 99 процентов ваших пользователей уйдут к конкурентам, которые смогли обойтись всего 10 кликами. Это очень важный момент, на который, к сожалению, не обращают внимания при организации курсов программирования и смежных дисциплин в ВУЗах даже на целевых специальностях.

Так, традиционно, цель формулируется следующим образом: “к 10 числу сего месяца оформить и сдать лабораторную работу на тему …”, при приеме работы внимание уделяется на контроль того, действительно ли данный студент выполнил эту работу сам или ему “помог” кто-то еще. Но не уделяется должного внимания вопросу контроля за качеством написания кода, эффективности алгоритма, наличию средств тестирования. Так “умело” вводя исходные данные для расчета можно избежать слабых мест алгоритма. Скажем, нет проверки исходного аргумента на ноль перед последующим использованием его при операции деления. Не уделяется внимание вопросу грамотного оформления кода, наличию комментариев, стилю именования переменных, функций, констант.

Исходный код понятен только самому разработчику, да и то очень недолго, до момента сдачи работы. Никакой дальнейшей поддержки и развития проекта нет. Такой термин как “самодокументируемый или самоописывающийся код” не известен. Нет проверок на исключительные ситуации, такие как нехватка памяти, отсутствие файлов, библиотек. Например, после открытия файла идет чтение из него данных, без предварительной проверки того, что файл был действительно открыт. С таким подходом разрабатывать коммерческий продукт нельзя. Хотя бы потому, что люди платят за него деньги, и хотят быть уверены, что ваш продукт не испортить настройки и файлы операционной системы, что он не повиснет, ему не потребуется какая то редкая библиотека dll, которую вы забудете поместить в установочный пакет и т.д. Особо больной вопрос об организации коллективной работы и ЖЦПО – жизненного цикла программного обеспечения (через стадии анализа, планирования до стадии сопровождения уже разработанного проекта), но об этом позже, гораздо позже.

Все же начинать нужно с простого. И что очень важно, в своих статьях я буду ориентироваться не на искушенных профессионалов, а на людей которые хотели бы попробовать себя в разработке 3d приложений, но не имеют опыта в программировании или он крайне не значителен. При этом я не могу умолчать об общих правилах и приемах связанных с проектированием, также буду уделять много внимания довольно простым вещам таким как кто такая переменная, зачем нужен цикл и функция. Но предполагаю, что вы будете придумывать и решать задачи основываясь и усложняя мои примеры. Если в какой то день мы рассмотрели программу, которая рисует текст расположенный по спирали, то сделайте так чтобы эта спираль вращалась или перемещалась. Очень важно осознавать, что наша конечная цель не тот самый трехмерный пинг-понг, а именно процесс его разработки, так чтобы в ходе его опробовать наибольшее количество приемов используемых в серьезном программировании.

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

Первоначальный вопрос, который мог бы прозвучать так: "и на каком языке программирования мы будем писать код?" по определению не верен. Если вы на коротке с физикой и математикой то вы можете писать на любом языке, в конце концов либо вы будете использовать средства opengl, directx либо создадите собственный их программный аналог/эмулятор, только вот вопрос в количестве необходимого времени. Второй подход основан на использовании наработок в виде библиотек 3d функций созданных другими людьми, так мы получаем возможность оперировать довольно высокоуровневыми объектами и понятиями, быстрее получая конечный код. А вопрос быстрого получения кода важен помимо технических сложностей еще и чисто психологически, и особенно он важен при коллективной разработке.

Если не получить в приемлемые сроки рабочий проект, то интерес начинает угасать, тем более если вам не платят за работу. Почитайте любое популярное издание на тему темпераментов и психологии людей. Применительно к разработке П.О. - классическая литература на эту тему: Эдвард Йордан «Смертельный марш. Полное руководство для разработчика программного обеспечения по выживанию в безнадежных проектах». Очень хорош Ф. Брукс с книгой “Мифический человеко-месяц, или как создаются программные системы”, именно ему принадлежит высказывание “нет серебряной пули”, о котором я упоминал раньше. И что тоже очень важно, разработка “движка” это, по сути, вершина (одна из многих) развития программиста. Только научившись работать с некоторым инструментом “на отлично”, пройдя через десяток проектов, вы можете грамотно сформулировать свои пожелания на основе опыта и создать инструмент который ускоряет разработку. Делать “движок” только потому, что “я не понял, как работает эта штука и потому решил сделать свою” просто не серьезно.

В любом случае, какой бы подход вы не избрали, но изучить базовые понятия математики в области геометрии, матричной алгебры, а также краткий курс физики вам все равно придется. Давайте, первый вопрос мы сформулируем не так “какой язык мы будем изучать”, а “какая библиотека 3d-функций делает то, что нам нужно”. А за изучением языка дело уже не станет. Фактически если вы умеете программировать на одном языке, то изучение другого это вопрос нескольких недель.

Я говорю именно об языке, а не всевозможных библиотеках, дополнениях. Вот как раз изучить новую библиотеку (скажем вы использовали для построения графического пользовательского интерфейса средства X, а потом решили перейти на средство Y). Здесь сроки приближаются к цифре порядка нескольких месяцев, а то и лет.

Итак, нам нужен движок 3d графики, который будет рисовать нам комнату, в которой будут происходить событий, сам мяч, ракетку. Начнем мы с того, что введем в адресную строку браузера адрес http://www.devmaster.net/engines/. По этому адресу располагается очень (действительно очень) хороший обзор доступных 3d движков и связанных с ними инструментов. Сначала вам необходимо решить поддержкой, каких возможностей (кратко перечислены ниже) должен обладать искомый вами движок, определиться с выбором языка, и после применения поиска, выбрать, уже ориентируясь на отзывы посетителей ресурса то, что вам нравится.

Характеристики 3d или game движков на сайте devmaster разделены на категории:



General Info – это общие характеристики движков, сюда входит: используемое api низкого уровня, на выбор directx, opengl, морально устаревший glide или режим software без поддержки аппаратных средств ускорения графики. Выбор между directx и opengl не играет особой роли за исключением возможной ориентации на кроссплатформенность, если ваш проект в перспективе будет работать под linux или mac, то directx не ваш выбор. Отдельный момент в том, что некоторые движки построены по принципу микроядра. Эта методика характерна для достаточно большого количества сложных (для простых она себя не оправдывает, известно, что не стоит из пушки стрелять по воробьям) проектов. И заключается в том, что создается базовый набор функций абстрагированных от специфики функций opengl или directx, которые составляют это микроядро (меньшая часть проекта) и вызываются из основной (большей части проект). Если необходимо перейти с directx на opengl, то нужно всего лишь заменить это микроядро, а не переписывать весь (абсолютно весь) код проекта заново. Так при запуске приложения появляется диалоговое окно настроек и выбора используемого микроядра. Если вы работали, например, с 3dstudio max, то при первом его запуске появляется диалог выбора используемых средств отрисовки: directx, opengl, или для совсем “бедных” software режим. И это не единственный пример.

Следующий параметр: Status – статус проекта, его возможные значения: Alpha, Beta, Productive/Stable, Inactive. Очевидно, что от проектов Inactive – заброшен или неактивен - нужно держаться подальше, равно как и от alpha, за betta внимательно присматриваем, а пользуемся Productive/Stable – версия стабильна и может быть использована при разработке сторонних проектов.

Действительно важный параметр Programming Language – язык программирования, выбирайте сами или воспользуйтесь моими рекомендациями далее по тексту. Список языков достаточно широк, но очевидно, что брать экзотические (в нашей, по крайней мере, стране) вещи не следует, так важной частью является приобретение широкого набора знаний применимых и в других областях программирования.

Следующий параметр General Features – всякое разное – здесь важно обратить внимание на наличие Object-Oriented Design – объекто-ориентированного дизайна. Вопрос о выборе средств и методики программирования основанной на ООП, и их специфики, оставим за кадром. Я лично убежденный сторонник ООП. Просто запомните простую вещь, если объем проекта уходит за пару тысяч строк без средств ООП вам будет его закончить гораздо сложнее, чем с помощью традиционного структурно-функционального подхода. ООП позволяет делать меньшее количество ошибок, требуя более вдумчивого подхода при проектировании. Это часто отпугивает начинающих разработчиков, жаждущих жить по лозунгу: “проще, максимально проще, и быстрее”. Экономия времени на начальных стадиях программирования без ООП будет многократно растеряна на более поздних его этапах. Про такое слово как повторное использование кода, можно практически забыть. Особый момент в том, что, возможно, вам не будет предоставлен выбор методики. Например, язык java - объектно-ориентирован и точка.

Важный параметр Plug-in Architecture – поддержка расширений и плагинов. Без комментариев, нужна и обязательна. Никогда не было и не будет ни одного более-менее сложного программного продукта, который не предоставлял возможности посторонним разработчикам и компаниями создавать дополнительные функции и расширения возможностей. Тот же 3dsmax, photoshop, или популярные среды программирования (eclipse, visual studio, idea) предоставляют эту возможность. “Заставьте работать на себя весь мир” – это просто отличный лозунг.

Очень важный параметр Save/Load System – поддержка механизмов чтения и сохранения информации об окружающем мире во внешних файлах. Эта возможность дает шанс наличию в проекте отдельного или встроенного редактора (построителя) мира. Вывод: нужно для любого проекта сложнее тетриса.

Следующий большой набор параметров: Game Features – вещи характерные в основном для игровых проектов. Сюда входят:

Networking System – поддержка работы по сети. Каждый современный язык имеет поддержку средств работы по сети. Так что если данная функциональность не реализована то ничего страшного. Кроме разве что проектов а-ля ММОРПГ, но начинающему разработчику они противопоказаны по определению.

Еще один параметр Tools & Editors – наличие редактора мира, встроенного языка программирования, специфического именно для данного проекта.

Важный параметр Sound & Video – поддержка звука, в том числе 3d, а также средств встраивания видео-потока в приложение, например для заставок.

Очень важный параметр Physics – физика нужна без сомнения, если конечно вы не хотите, чтобы ваш приключенец подобно приведению проходил сквозь стены и потолки. Очень хорошая тенденция – не реализация в рамках проекта очередного доморощенного физического движка, а создание на основе plugin технологии подключения средств одного из признанных лидеров: Newton, ode (open dynamics engine), tokamak.

Следующий большой набор параметров под общим названием: Graphics Features.

Сделаем так если вы еще не знаете чем отличается Bump Texture Mapping от Environment Map-Bump Mapping то неплохо бы почитать супер-руководство http://www.ixbt.com/video/3dterms.html (это как введение), а это для продолжающих http://www.ixbt.com/video/terms2k5.shtml. Ничего лучшего на русском языке я еще не видел.

Общие рекомендации, пожелания и прочая



Несколько общих рекомендаций: всегда посетите сайт проекта и обратите внимание на дату его последнего обновления, а также на то, как регулярно становятся доступными очередные версии библиотеки, разумеется, что этот период сильно зависит от правил и стиля разработки. Так одни компании или сообщества предпочитают делать раз в год, а то и два одно большое изменение и называть версии 1, 2, 3 и т.д. Другие же предпочитают вносить изменения буквально каждый день и нумеровать их 0.1001, 0.1002 и т.д.. Разумеется, что во втором случае вряд ли вам будет доступна для скачивания ссылка на архив проекта, обычно есть доступ к, так называемым, “nightly build”.

Суть “ночной сборки” в том что, каждую ночь ровно в полночь (шучу, конечно) разработчики завершают очередное изменение проекта. Которое тестируются, зачастую с помощью средств автоматического тестирования и оценки качества покрытия кода, после чего становится доступным вам либо ссылка на все файлы нужные для работы “движка” в виде архива, либо, что для меня всегда было более предпочтительно, доступ осуществляется с помощью средств CVS или SVN.

Следующий момент, на который вам следует обращать внимание при выборе движка – это степень развитости и активности коммьюнити. Не ожидайте что разработчики (ядро команды) будет реагировать на ваши, написанные на корявом английском языке вопросы, типа “как сделать так чтобы куб был синего цвета”. В большинстве своем эти люди занимаются программированием в свое удовольствие, в свое личное время и без особо коммерческого интереса, так что, согласитесь сами, отвечать на такие вопросы – удовольствия мало.

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

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

Вот еще один фактор, говорящий о зрелости проекта – это наличие подпроектов. Как бы разработчики не старались, но сделать сразу все просто не возможно, и уж тем более качественно. Например, для любого 3d движка больной вопрос о разработке набора элементов управления а-ля windows, т.е. кнопки, падающие списки, менюшки, текстовые поля с нормальной поддержкой Unicode (проще говоря, чтобы вы могли вводить в данные текстовые поля текст на русском или китайском языке без лишних танцев с бубном).

Если ваш проект не имеет таких стандартных средств, но нашелся какой то Джон Смит, который создал свой под-проект основанный на средствах родительского и реализующий данную функциональность, то это большой плюс к критериями выбора движка. Если же таких Джонов Смитов несколько, это уже не два плюса, а целых четыре. Чем больше людей хочет развивать проект, тем качественнее его внутренняя архитектура, тем грамотнее организован api – набор функций и объектов которые можно использовать и вызывать из вашего приложения, использующего данный api, тем удобнее лицензионная политика, и тем больше шанс, что вы не окажитесь у разбитого корыта спустя некоторое время. Увы, но историй об провалившихся проектах гораздо больше, чем о тех, которые были успешны.

В следующей статье серии я сделаю краткий обзор бесплатных 3d-движков. А также определимся с выбором как используемого “движка” так и языка программирования.