Pull to refresh

DOOM 3 BFG — обзор исходного кода: введение (часть 1 из 4)

Reading time 6 min
Views 73K
Часть 1: Введение.
Часть 2: Многопоточность
Часть 3: Рендеринг (Прим. пер. — в процессе перевода)
Часть 4: Doom classic — интеграция (Прим. пер. — в процессе перевода)

26 ноября 2012 ID Software выпустила исходный код Doom 3 BFG edition (всего через месяц после появления игры на прилавках магазинов). Движок idTech4, которому уже почти 10 лет, был обновлен решениями, используемыми в idTech 5 (Rage — первая игра на этом движке), и с его исходным кодом ознакомиться было очень интересно.

Я бы назвал движок «idTech4 улучшенный», т.к. по сути это idTech4, но с использованием элементов idTech5:
  • Систему управления потоками (Threading system)
  • Звуковую систему (Sound system)
  • Систему управления ресурсами (Resources system)

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

Я надеюсь, что это вдохновит людей разбираться в исходном коде, улучшать свои навыки и становиться лучшими инженерами.

Первый контакт


Знакомство с Doom 3 BFG впечатляет, т.к. для запуска из исходников необходимо проделать всего 2 шага:
  1. Получить исходники, расположенные на GitHub:
     git clone https://github.com/id-Software/DOOM-3-BFG
    

  2. Открыть Visual Studio 2010 Express и нажать F8 для компиляции. Готово!

Примечание: Если Direct3D SDK установлен, полный проект компилируется менее чем за минуту, выдав 5 минимальных предупреждений.

Режим отладки


Всего 3 шага необходимо, чтобы начать мастерить в Visual Studio 2010 Express:
  1. В комадной строке отладки указать базовый путь:
     +set fs_basepath "C:\Program Files\Steam\SteamApps\common\DOOM 3 BFG Edition" +set r_fullscreen 0
    

  2. Открыть проект «Doom3BFG».
  3. Нажать F5



Удобочитаемость исходного кода


Подмножество C++:

Doom 3 BFG написана на C++, языке настолько великом, что он может быть использован как для создания великолепного кода, так и для такой мерзости, от которой ваши глаза будут кровоточить. К счастью ID Software использовало подмножество языка С++, близкое к «С с классами», которое будет не таким сложным для восприятия:
  • Отсутствуют исключения
  • Нет ссылок (используются указатели)
  • Минимальное использование шаблонов
  • Константы повсюду
  • Классы
  • Полиморфизм
  • Наследование

И несмотря на многопоточность, в коде не используются смарт-указатели или Boost. Какое облегчение (ведь это то, что обычно делает код нечитаемым).

Комментарии

Комментариев много и они довольно полезны, так как они, как правило, одним предложением описывают то, что просходит в наиболее важных местах следующего блока. Вот пример из 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 и 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 возникают проблемы с выделением памяти. Это порождает ошибки которые трудно отследить.


Изменения связанные с разработкой для консолей:


Ориентация на Xbox 360 и PS3 в проекте, изначально ориентированном на ПК привело ко многим важным обновлениям:
  1. Как упоминалось ранее вся игра содержится в одном исполняемом файле.
  2. В игре для хранения различных частей используются файлы PAK (являющтеся ZIP архивами). Высокая латентность DVD приводов толкнуло ID Software к следующему распределению ресурсов: один файл, содержит всё необходимое для одной загрузки уровня.
  3. Игровые активы были текстовыми, но для того, чтобы снизить время загрузки, некоторые из активов, таких как модели и анимация теперь двоичные ( .bmd5mesh и .bmd5anim ).
  4. Doom 3 разрабатывался для работы с разрешением 640x480 с соотношением сторон 4:3. В настоящее время телевизоры и мониторы чаще всего имеют соотношение сторон 16:9, поэтому все меню были сделаны заново. Вероятно, в целях ускорения разработки, она реализуются на Adobe Flash. Doom 3 BFG использует собственный интерпретатор Flash (/neo/swf/ ). И снова Flash используется для того, чтобы ускорить разработку.
  5. Рендеринг шейдеров был переписан с использованием GLSL 1.5. HLSL шейдеры могут преобразовываться на лету.
  6. Для получения приемлимой частоты кадров фонарик нельзя было использовать вместе с оружием. (Прим. пер. — в оригинале есть фраза «Now with Doom 3 BFG it can be duck taped on weapons but for performances reason it won't cast any shadows. » Вероятнее всего имеется ввиду не «duck taped», а «duct taped» — скотч, т.е. «Теперь же, в Doom 3 BFG он может быть прикреплен к оружию...»)
  7. Т.к. меню теперь кросплатформенно PC во многом утратило настройки рендеринга: мы получаем простую версию, которая используется как в ПК, так и консолях.


Многопоточность


За 10 лет, прошедших между разработкой старого и нового движка произошел сдвиг парадигмы: «бесплатный сыр» закончился, и игровые движки должны быть разработаны с использованием многопоточности. Поэтому наиболее привлекательной вещью для чтения в Doom III BFG является idTech5 Threading архитектура. (Подробный обзор во 2ой части перевода).

Рендеринг


Тут 2 главных изменения:
  • Работает на Open GL 3.2 Совместимость профиля с использованием GLSL шейдеров 1.5.
  • Использование многопоточности (до четырех потоков, работающих одновременно).
(Подробный обзор в 3ей части перевода)

Doom classic


Doom III BFG позволяет играть в Doom 1 и Doom 2. На первый взгляд простая задача интегрировать старый движок Doom1 в новый Doom 3 BFG: просто перенаправить все входы / выходы! Но с учетом режима разделенного экрана на PS3 и Xbox360 это реализуемо не так-то просто. (Подробный обзор в 4ой части перевода)



Пост является переводом, но т.к. публикуюсь из песочницы — не могу изменить тип поста. Последующие части будут оформлены правильно. Ошибки перевода, опечатки с радостью исправлю, пишите в лс.

Оригинал первой части — Fabien Sanglard
Tags:
Hubs:
+105
Comments 85
Comments Comments 85

Articles