26 ноября 2012 ID Software выпустила исходный код Doom 3 BFG edition (всего через месяц после появления игры на прилавках магазинов). Движок IDTech 4, которому уже почти 10 лет был обновлен до IDTech 5 (Rage — первая игра на этом движке), и с его исходным кодом ознакомиться было очень интересно.
Хочу заметить, что idTech5 многое перенял у idTech4:
- Систему управления потоками (Threading system)
- Звуковую систему (Sound system.)
- Систему управления ресурсами(Resources system.)
До сих пор наиболее привлекательным аспектом является система управления потоками: Doom 3 была разработана на заре эпохи многоядерных систем, когда немногие компьютеры еще использовали SMP. Теперь правила изменились, даже телефонов оснащены несколькими ядрами и игровой движкок должен быть многопоточным, чтобы использовать весь потенциал машины.
Я надеюсь, что это вдохновит людей разбираться в исходном коде, улучшать свои навыки и становиться лучшими инженерами.
Часть 1: Введение.
Часть 2: Многопоточность. (Прим. пер. — в процессе перевода)
Часть 3: Рендеринг. (Прим. пер. — в процессе перевода)
Часть 4: Doom classic — интеграция (Прим. пер. — в процессе перевода)
Первый контакт
Знакомство с Doom 3 BFG впечатляет, т.к. для запуска из исходников необходимо проделать всего 2 шага:
- Получить исходники, расположенные на GitHub:
git clone https://github.com/id-Software/DOOM-3-BFG
- Открыть Visual Studio 2010 Express и нажать F8 для компиляции. Готово!
Примечание: Если Direct3D SDK установлен, полный проект компилируется менее чем за минуту, выдав 5 минимальных предупреждений.
Режим отладки
Всего 3 шага необходимо, чтобы начать мастерить в Visual Studio 2010 Express:
- В комадной строке отладки указать базовый путь:
+set fs_basepath "C:Program FilesSteamSteamAppscommonDOOM 3 BFG Edition" +set r_fullscreen 0
- Открыть проект «Doom3BFG».
- Нажать F5
Удобочитаемость исходного кода
C++ подмножество:
Doom 3 BFG написана на C++, языке настолько великом, что он может быть использован как для создания великолепного кода, так и для такой мерзости, от которой ваши глаза будут кровоточить. К счастью ID Software использовало подмножество языка С++, близкое к «С с классами», которое будет не таким сложным для восприятия:
- Отсутствуют исключения
- Нет ссылок (используются указатели)
- Минимальное использование шаблонов
- Константы повсюду
- Классы
- Полиморфизм
- Наследование
И несмотря намногопоточность, в коде не используются смарт-указатели или Boots. Какое облегчение (ведь это то, что обычно делает код нечитаемым).
Комментарии
Комментариев много и они довольно полезны, так как они, как правило, одним предложением описывают то, что просходит в наиболее важных местах следующего блока. Вот пример из ParallelJobList.cpp
:
int idJobThread::Run() {
threadJobListState_t threadJobListState[MAX_JOBLISTS];
int numJobLists = 0;
int lastStalledJobList = -1;
while ( !IsTerminating() ) {
// fetch any new job lists and add them to the local list
if ( numJobLists < MAX_JOBLISTS && firstJobList < lastJobList ) {
threadJobListState[numJobLists].jobList = jobLists[firstJobList & ( MAX_JOBLISTS - 1 )].jobList;
threadJobListState[numJobLists].version = jobLists[firstJobList & ( MAX_JOBLISTS - 1 )].version;
threadJobListState[numJobLists].signalIndex = 0;
threadJobListState[numJobLists].lastJobIndex = 0;
threadJobListState[numJobLists].nextJobIndex = -1;
numJobLists++;
firstJobList++;
}
// if the priority is high then try to run through the whole list to reduce the overhead
// otherwise run a single job and re-evaluate priorities for the next job
bool singleJob = ( priority == JOBLIST_PRIORITY_HIGH ) ? false : jobs_prioritize.GetBool();
// try running one or more jobs from the current job list
int result = threadJobListState[currentJobList].jobList->RunJobs( threadNum, threadJobListState[currentJobList], singleJob );
В общем читатель получает непосредственное понимание каждой части алгоритма, и я надеюсь, что это вдохновит людей писать лучший код: ведь сейчас разрабатывая ПО, не главное быть большим асом чем другие. Не менее важно уметь работать в команде, создавая код:
- Изящно спроектированный
- Легко читаемый, с использованием комментариев где это нужно
Doom 3 BFG занимает высокие позиции по обоим этим позициям.
Что изменилось?
- 2 проекта «Game» (Doom III classic и Ressurection) объединены в один проект
- Убран cUrl
- Убрано глупое название DoomDLL… Это было на самом деле генерации DOOM3.EXE
- Убраны устаревшие инструменты Maya для экспорта md5 модели, анимации и пути камеры.
- Убран TypeInfo, взамен добавлен RTTI/Introspection.
Обозреватель решений (solution explorer) в Visual Studio стал заметно чище (до и после):
Подпроекты Doom 3 BFG
Projects | Builds | Observations |
Amplitude | Amplitude.lib | Используется в Doom Classic: Инструмент для регулировки амплитуды WAV. |
Doom3BFG | Doom3BFG.exe | Движок Doom 3 BFG. |
doomclassic | doomclassic.lib | Серьезно переработанный движок Doom1/2. |
external | external.lib | Исходники jpeg-6 and zlib. |
Game-d3xp | Game-d3xp.lib | Единая библиотека игры, включающая оригинальную игру + расширения + новые уровни. Обратите внимание, что теперь она собирается в статическую библиотеку вместо DLL. |
idLib | idLib.lib | Пакет инструментов id software для работы с файловой системой. |
timidity | timidity.lib | Используется вДум Classic для преобразования MIDI-файлов в формат WAV. |
Новая архитектура
Архитектура существенно отличается от оригинального Doom III: cейчас все компилируется в один монолитный исполняемый файл (оригинальный Doom III компилировался в один исполняемый файл и одну DLL содержащую игровую логику). Это было сделано по двум причинам (со слов с основного разработчика Брайана Харриса):
- Консоли, такие как PS3/Xbox360 не лучшим образом поддерживают библиотеки DLL.
- Ускорить скорость разработки. Используя библиотеки dll, возникают проблемы с выделением памяти. Это порождает ошибки которые трудно отследить .
Изменения связанные с разработкой для консолей:
Ориентация на Xbox 360 и PS3 в проекте, изначально ориентированном на ПК привело ко многим важным обновлениям:
- Как упоминалось ранее вся игра содержится в одном исполняемом файле.
- В игре для хранения различных частей используются файлы PAK (являющтеся ZIP архивами). Высокая латентность DVD приводов толкнуло ID Software к следующему распределению ресурсов: один файл, содержит всё необходимое для одной загрузки уровня.
- Игровые активы были текстовыми, но для того, чтобы снизить время загрузки, некоторые из активов, таких как модели и анимация теперь двоичных (. bmd5mesh и. bmd5anim ).
- Doom 3 была разрабатывался для работы с разрешением 640x480 с соотношением сторон 4:3. В настоящее время телевизоры и мониторы чаще всего имеют соотношение сторон 16:9, поэтому все меню были сделаны заново. Вероятно, в целях ускорения разработки, они реализуются на в Adobe Flash. Doom 3 BFG использует собственный интерпретатор Flash (/neo/swf/ ). И снова Flash используется для того, чтобы ускорить разработку.
- Рендеринг шейдеров был переписан с использованием GLSL 1.5. HLSL шейдеры могут преобразовываться на лету.
- Для получения приемлимой частоты кадров лазерный прицел теперь не может быть использован вместе с оружием.
- Т.к. меню теперь кросплатформенно PC во многом утратило настройки рендеринга: мы получаем простую версию, которая используется как в ПК, так и консолях.
Многопоточность
За 10 лет, прошедших между разработкой старого и нового движка произошел сдвиг парадигмы: «бесплатный сыр» закончилась, и игровые движки должны быть разработаны с использованием многопоточности. Поэтому наиболее привлекательной вещью для чтения в Doom III BFG является idTech5 Threading архитектура. (Подробный обзор во 2ой части перевода).
Рендеринг
Тут 2 главных изменения:
Использование многопоточности (до четырех потоков, работающих одновременно).
(Подробный обзор во 3ей части перевода)
Doom classic
Doom III BFG позволяет играть в Doom 1 и Doom 2. На первый взгляд простая задача интегрировать старый движок Doom1 в новый Doom 3 BFG: просто перенаправить все входы / выходы! Но с учетом режима разделенного экрана на PS3 и Xbox360 это реализуемо не так-то просто. (Подробный обзор во 4ой части перевода)
Пост является переводом, но т.к. публикуюсь из песочницы — не могу изменить тип поста. Последующие части будут оформлены правильно. Ошибки перевода, опечатки с радостью исправлю, пишите в лс.
Автор: PopeyetheSailor