Duke nukem для linux

Содержание
  1. It’s time to kick ass and chew bubble gum, and I’m all outta gum!
  2. Join our community
  3. Join us on Discord or visit our forums.
  4. Questions?
  5. Once you’ve downloaded EDuke32, you’ll probably want to read our wiki page on installation and configuration, as well as the FAQ if you have any problems.
  6. Packed with features—»shake it, baby!»
  7. Duke nukem для linux
  8. Ubuntu-desktop.ru
  9. Установи Linux! Стань свободным!
  10. DUKE NUKEM 3D — КУЛЬТОВАЯ КОМПЬЮТЕРНАЯ ИГРА В ЖАНРЕ ШУТЕРА ОТ ПЕРВОГО ЛИЦА
  11. Установка игры Duke Nukem 3D в Linux Ubuntu (14.04)
  12. Анализ исходного кода Duke Nukem 3D: Часть 1
  13. Происхождение
  14. Первый контакт
  15. Сборка
  16. Погружение в процесс
  17. Обзор библиотеки движка
  18. Обзор игрового модуля
  19. Унаследованный исходный код
  20. Chocolate Duke Nukem 3D
  21. Внутренности движка Build
  22. Важнейшая концепция: система порталов
  23. Обзор рабочего цикла
  24. 1. С чего начинать рендеринг?
  25. Подробности об inside
  26. Эпоха вычислений с фиксированной запятой и вездесущие векторные произведения
  27. Внутри вогнутого полигона
  28. 2. Портальные и непрозрачные стены
  29. Генерирование групп
  30. Использование групп
  31. Визуализация стен/полов/потолков
  32. 3. Пауза
  33. 4. Рендеринг спрайтов
  34. Профайлинг
  35. Интересные факты о VGA и VESA
  36. Звуковой движок
  37. Унаследованный код
  38. Рекомендуемое чтение

It’s time to kick ass and chew bubble gum, and I’m all outta gum!

Per-pixel dynamic lighting and realtime shadows. groovy! Polymer renderer requires a bad-ass video card.

More Polymer greatness.

Hollywood Holocaust with classic textures

EDuke32 is an awesome, free homebrew game engine and source port of the classic PC first person shooter Duke Nukem 3DDuke3D for short—to Windows, Linux, Mac OS X, FreeBSD, several handhelds, your family toaster, and to your girlfriend’s vibrator. We’ve added thousands of cool and useful features and upgrades for regular players and additional editing capabilities and scripting extensions for homebrew developers and mod creators. EDuke32 is open source software that is completely free to use for all non-commercial purposes.

Created by Duke4.net community leader Richard «TerminX» Gobeille and a team of elite ninja programmers including Pierre-Loup «Plagman» Griffais, Philipp «Helixhorned» Kutin, and Evan «Hendricks266» Ramos (based on work by Todd Replogle/Ken Silverman/Jonathon Fowler/Matt Saettler), EDuke32 is the undeniable king of Duke Nukem 3D ports.

EDuke32 is licensed under the GNU GPL and the BUILD license.

Join our community

Join us on Discord or visit our forums.

Questions?

Once you’ve downloaded EDuke32, you’ll probably want to read our wiki page on installation and configuration, as well as the FAQ if you have any problems.

Packed with features—»shake it, baby!»

Here are some of Polymer’s features:

  • Real time dynamic colored lighting and shadow mapping
  • Specular and normal map support
  • md3/jpg/png/tga support
  • Fog density (sector visibility) support—corrects the dull appearance and extreme lack of contrast in early OpenGL ports
  • Fullbrights and glow maps (for glowing red pigcop eyes, etc!)
  • Detail textures
  • Blending between model animations
  • Support for colored fog
  • Individual brightness/contrast/gamma adjustment
  • Full widescreen monitor support plus manual fov and aspect ratio adjustment
  • VSync support
  • . and more!

I first saw Duke3D running on a computer in a Wal-Mart in late December of 1995. I was 11 years old. Unknown to me, it was an illegally distributed beta of what was to become Duke Nukem 3D 1.0, released in January of the next year.

After seeing Duke in action for the first time, I was hooked! I had seen games like Wolfenstein 3D, Doom and Heretic before but this was different. Not long after that, we got the first family computer, and I got the first episode of Duke on CD-ROM.

I immediately got nosy and said «hey, what are these ‘CON’ files?» Atomic Edition came for Christmas that year. The rest is history!

BUILD engine technology originally created by Ken Silverman, non-GPL rendering and engine technology used in EDuke32 available under BUILDLIC.

Think EDuke32 rocks and want to link us? Use the above button on the right! This site best viewed in Firefox or Chrome. Fight Spam! Click Here!

Источник

Duke nukem для linux

Предлагаю вашему вниманию статьи Максима Вшивкова (aka BuRaTiNoS) на тему «Как запустить DOOM и Duke Nukem на Linux». С оригиналом можно ознакомиться на сайте Mintlinux. Здесь публикуется с разрешения самого автора. Орфография и стиль полностью сохранены.

Доброго времени суток. Добавляем репозиторий популярной когда то игрушки. Мне она нравится и по сей день. Я вообще любитель старых-добрых игрушек.

Собственно тут вообще нет ничего сложного.

EDuke32 — движок культового PC шутера от 1-го лица Duke Nukem 3D для Windows, Linux и OS X, который добавляет много интересных вещей и дополнений для игроков, а также включает в себя средства для редактирования карт.

Немного о игре:
* Игра полностью нативна и запускается без всяких эмуляторов.
* Позволяет выбирать между новым, модернизированным рендером с OpenGL ускорением и классическим, софтверным.
* Единственный активно разрабатываемый и поддерживаемый порт Duke Nukem 3D за последние годы.
* Бесконечное количество модов и расширений, которые изменяют игровой процесс.
* Quake-стайл консоль с подсветкой, историей команд и т.д.
* Единственный порт, который может запустить High Resolution Pack со всеми его достоинствами.

добавляем реп для своей архитектуры, для Кати соответственно я брал реп Натти, для Исадоры — реп Lucid Lynx.
Либо, для Кати [Mint11]
Код PHP:
deb http://apt.duke4.net natty main
deb-src http://apt.duke4.net natty main
Для Айсидоры [Mint9]
Код PHP:
deb http://apt.duke4.net lucid main
deb-src http://apt.duke4.net lucid main
Добавляем ключ:
Код PHP:
wget -q http://apt.duke4.net/key/eduke32.gpg -O- | sudo apt-key add —
Обновляем кеш, и ставим. Кому как удобней, через ЦП, Синаптик, Терминал, пакет eduke32. Далее берем файл из оригинальной игры DUKE3D.GRP переименовываем его в нижний регистр, ложим в папку .eduke32 и запускаем игру.
Можно например, взять архив с игрой тут: http://games-history.ru/?division=game&id=141

В виде DOS архива с игрой

Настраиваем разрешение и т.д и жмем Старт

Так как являюсь поклонником исключительно старых игр, приверженцем шутеров и исключительно Doom, Quake, Duke Nukem и т.д и т.п. И категорически не перевариваю всякие Дум 3, Квейк4. То нетрудно догадаться, что время уделю старой игрушке. Впрочем, если повезет, то последующие, мини руководства тоже

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

Я же расскажу в 2х словах, как поставить боле менее популярные и распространенные порты : Skulltag и Zdoom. Человеческий вариант игры, как для сингл так и онлайн варианта.А так же в дополнение добавлю пару слов о модах которые мне очень понравились. А не то что нам суют из реп. Эти порты меня как радовали когда то в Виндовсе, так радуют и в никсах.

Я например пользую ЗДум исключительно для сингл, погонять с компом, убить время, разрядиться. Скуллтаг, более как вариант сетевой игры.

Всё что нам понадобится, есть в репозитории и установиться автоматом.

Итак , добавляем реп.

Код PHP:
deb http://skulltag.net/download/files/release/deb stable multiverse

Далее, обновляем список пакетов.

И устанавливаем сам движек (у кого к чему больше лежит душа)
sudo apt-get install skulltag
sudo apt-get install zdoom
После как все скачается и установиться, в пункте меню «Игры» у нас всё это и появится.

Перед тем как запускать, нужно создать папку .skulltag в домашней директории. Туда скопировать WAD файлы, от оригинальных игр.

Взять их можно например отсюда http://old-games.ru, вбив в поиск Doom. http://old-games.ru Далее можно запускать игру Приложения>Игры>Skulltag/Zdoom

Появится вот это окошко, с WADами выбираем , жмем «ОК»

Скорее всего в Skulltag возникнет проблема с сохранением игры, точнее с невозможностью ее записать и сохранить. Решается всё достаточно просто, открываем файл с помощью любого текстого редактора

/.skulltag/skulltag.ini , ищем в нём строку «save_dir=» и приводим к такому виду «save_dir=

Для таких как я, любителей погонять Онлайн, что бы насладиться игрой от и до, и испытать всю полноту чувств.

Нужно установить утилиту Doomseeker.

Открываем терминал :
Код PHP:
sudo apt-get install doomseeker-skulltag
С помощью утилиты, осуществляется поиск и создание серверов.

Запускается она из меню Игры>Doomseeker

Настраивается это дело, примерно так :

Теперь, как и обещал, пару слов о модах, я играю исключительно Alanguns (огромное кстати спасибо Автору столь замечательного и играбельного мода). Выбрал и остановился именно на нем, так как. Мод не только исключительно оружейный ( присутствует куча оружия), но так же есть и много всяческих разнообразных, монстров. Например и из знаменитого Дюка. Да и в соотношении : простота запуска, все есть + ничего лишнего, да и сравнительно не большой вес! Что тоже не маловажно. Что то в пределах 12 Мб. А то иной раз качаеш хваленые — расхваленые метров эдак под 200, мучаешся с запуском, и в итоге. болт!

Запускается игра с модом, примерно по такому принципу, можно из Терминала, а можно для простоты и удобства, Кнопку запуска в меню забацать. Код PHP:
skulltag -file /home/user/.skulltag/Alandoguns.WAD

Читайте также:  Драйвера для windows 10 просмотр

Большинство предоставленного здесь материала является цитированием со старых номеров компьютерных журналов, таких, как «Мир ПК» или «Весь Компьютерный Мир». К сожалению, все мои попытки связаться с этими изданиями по поводу вопроса о цитировании были безуспешны. Издания упорно хранили молчание. Что я разрешил себе расценивать как знак согласия, указывая, тем не менее, повсюду как выходные данные издания (с работающей ссылкой на Интернет-представительство), так и автора публикации. Тем более, что, в силу срока давности этих публикаций, вряд ли материал можно рассматривать как коммерческий или рекламный, пусть даже названия фирм здесь и присутствуют (уж без этого никуда). Ежели появятся какие претензии по оному поводу, прошу издания связаться со мной

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

Источник

Ubuntu-desktop.ru

Установи Linux! Стань свободным!

DUKE NUKEM 3D — КУЛЬТОВАЯ КОМПЬЮТЕРНАЯ ИГРА В ЖАНРЕ ШУТЕРА ОТ ПЕРВОГО ЛИЦА

Duke Nukem 3D — культовая компьютерная игра в жанре шутера от первого лица, созданная компанией 3D Realms (подразделение Apogee) в 1996 году. Duke Nukem 3D является логическим продолжением игр серии Duke Nukem, но если первые две игры из серии были двухмерными платформерами, то третья часть выполнена в популярном на то время стиле Doom (псевдотрехмерные коридоры, вид от первого лица, сражения с применением различного вида холодного, огнестрельного, а также вымышленного оружия). Фактически, Duke Nukem 3D был ответом компании Apogee на серию игр Doom, а также на Heretic и Hexen от компании id Software.

Установка игры Duke Nukem 3D в Linux Ubuntu (14.04)

Для начала чтобы играть в Duke Nukem 3D в Linux Ubuntu необходимо установить движок EDuke32.
EDuke32 — движок культового PC шутера от 1-го лица Duke Nukem 3D для Windows, Linux и OS X, который добавляет много интересных вещей и дополнений для игроков, а также включает в себя средства для редактирования карт.

Установка движка EDuke32

sudo add-apt-repository «deb http://apt.duke4.net precise main»

sudo apt-get update
sudo apt-get install eduke32

Если удалось запустить движок то все практически получилось, теперь необходимо в папку .eduke32 добавить файл DUKE3D.GRP который необходимо взять с оригинальной игры Duke Nukem 3D.

Скачиваем и устанавливаем оригинальную DOS игру:

Устанавливаем утилиту Dosbox для установки игры

Запуск установщика игры

После исполнения команды запустится установщик игры, в настройках установщика ни чего не меняйте, просто нажимайте ENTER.

После установки игры выйдите из установщика набрав exit

В домашней папке у Вас появилась папка DUKE3D, скопируйте файл DUKE3D.GRP и вставьте в папку .eduke32, папка .eduke32 находится в домашней папке, для ее просмотра в опциях диспетчера файлов Nautilus включите опцию «Показывать скрытые файлы»

Наберите в терминале — eduke32


Выберите необходимое Вам разрешение экрана, установите при необходимости галочку па против пункта Fullscreen (во весь экран).

Источник

Анализ исходного кода Duke Nukem 3D: Часть 1

Уйдя с работы в Amazon, я провёл много времени за чтением отличного исходного кода.

Это оказался трудный опыт: сам движок имеет большую важность и высоко ценится за свою скорость, стабильность и потребление памяти, но мой энтузиазм столкнулся с исходным кодом, противоречивым в отношении упорядоченности, соблюдения рекомендаций и комментариев/документации. Читая код, я многое узнал о унаследованном коде и о том, что позволяет программному обеспечению жить долго.

Как обычно, я переработал свои заметки в статью. Надеюсь, она вдохновит вас на чтение исходного кода и совершенствование своих навыков.

Хочу поблагодарить Кена Силвермана (Ken Silverman) за вычитку этой статьи: его терпеливость и добросовестные ответы на мои письма были важны для меня.

Происхождение

Duke Nukem 3D — не одна, а две базы кода:

  • Движок Build: обеспечивает рендеринг, работу с сетью, файловой системой и службы кэширования.
  • Игровой модуль: использует службы Build для создания игры.

Зачем нужно было такое разделение? Потому что в 1993 году, когда началась разработка, только у немногих людей были навыки и рвение, необходимые для создания хорошего 3D-движка. Когда 3D Realms решила написать игру, которая станет конкурентом Doom, ей нужно было найти мощную технологию. И в этот момент на сцене появляется Кен Силверман.

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

Силверман напишет новый движок для 3D Realms, но сохранит за собой исходный код.

Он предоставит только двоичную статическую библиотеку ( Engine.OBJ ) с файлом заголовка Engine.h . Со своей стороны, команда 3D Realms возьмёт на себя работу над игровым модулем ( Game.OBJ ) и выпустит финальный исполняемый DUKE3D.EXE .

К сожалению, исходный код обеих частей игры не был открыт одновременно:

  • Исходный код движка был выпущен Кеном Силверманом 20 июня 2000 года.
  • Исходный код игрового модуля был выпущен 3D Realms 1 апреля 2003 года.

В результате полный исходный код стал доступен только через 7 лет после выпуска игры.

Интересный факт: название движка «Build» было выбрано Кеном Силверманом при создании каталога для нового движка. Он воспользовался тезаурусом, чтобы найти синонимы к слову «Construction».

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

Поскольку исходный код выпущен давным-давно (он был предназначен для компилятора Watcom C/C++ и систем DOS), я попытался найти что-то похожее на Chocolate doom: порт, точно воспроизводящий игровой процесс Duke Nukem 3D, таким, каким он был в 90-х, и беспроблемно компилирующийся на современных системах.

Выяснилось, что сообщество исходного кода Duke Nukem уже не слишком активно: многие порты снова устарели, некоторые созданы для MacOS 9 PowerPC. До сих пор поддерживается только один (EDuke32), но он слишком сильно эволюционировал по сравнению с оригинальным кодом.

В результате я начал работать с xDuke, хотя он и не компилировался на Linux и Mac OS X (что исключило использование XCode: отличного IDE для чтения кода и профайлинга).

xDuke, сделанный на Visual Studio, точно воспроизводит оригинальный код. Он содержит два проекта: Engine и Game. Проект «Engine» компилируется в статическую библиотеку ( Engine.lib ), а проект «Game» (содержащий метод main ) связывается с ним для генерирования duke3D.exe .

При открытии VS исходники движка выглядят довольно неприветливо из-за сложных имён файлов ( a.c , cache1d.c ). Файлы эти содержат нечто враждебное глазу и мозгу. Вот один из множества примеров в файле Engine.c (строка 693):

Примечание: если имя файла/переменной содержит цифру, то это, вполне возможно, не очень хорошее имя!
Интересный факт: последняя часть кода game.c содержит черновик сценария Duke V!
Примечание: порт xDuke использует SDL, но преимущество кроссплатформенного API утеряно из-за таймеров WIN32 ( QueryPerformanceFrequency ). Похоже, что использованный SDL Timer слишком неточен для эмуляции частоты 120 Гц в DOS.

Сборка

Разобравшись с SDL и расположением заголовком/библиотек DirectX, можно собрать код за один щелчок. Это очень приятно. Последнее, что осталось — достать файл ресурсов DUKE3D.GRP , и игра запустится… ну, или типа того. Похоже, у SDL есть какие-то проблемы с палитрой в Vista/Windows 7:

Запуск в оконном режиме (или лучше в Windows 8) кажется решает проблему:

Погружение в процесс

Теперь игра работает. За несколько секунд Build предстаёт во всё своём блеске, демонстрируя:

  • Наклонные потолки
  • Реалистичное окружение
  • Возможность свободного падения
  • Ощущение истинного 3D.

Последний пункт, наверно, больше всего повлиял на игроков в 1996 году. Уровень погружения был непревзойдённым. Даже когда технология достигла своего предела из-за двухмерных карт, Тодд Реплогл (Todd Replogle) и Аллен Блум (Allen Blum) реализовали «эффекторы секторов» позволявшие телепортировать игрока и усиливавшие ощущение погружения в трёхмерный мир. Эта функция используется в легендарной карте «L.A Meltdown»:

Когда игрок запрыгивает в вентиляционную шахту:

Срабатывают эффекторы секторов и перед «приземлением» телепортируют игрока совершенно в другое место карты:

Хорошие игры медленно стареют, и Duke Nukem не стала исключением: двадцать лет спустя в неё всё ещё невероятно интересно играть. А теперь мы ещё и можем изучить её исходники!

Обзор библиотеки движка

Код движка находится в одном файле из 8503 строк и с 10 основными функциями ( Engine.c ) и в двух дополнительных файлах:

  • cache1.c : содержит виртуальную файловую систему (sic!) и процедуры системы кэширования.
  • a.c : реализация на C воссозданного обратной разработкой кода, который был высокооптимизированным x86-ассемблером. Код работает, но читать его — огромная мука!

Три модуля трансляции и несколько функций составляют высокоуровневую архитектуру, которую сложно понять. К сожалению, это не единственные сложности, с которыми придётся столкнуться читателю.

Внутренностям движка Build я посвятил целый раздел (см. ниже).

Обзор игрового модуля

Игровой модуль целиком построен поверх модуля движка, системные вызовы операционной системы используются процессом. Всё в игре выполняется через Build (отрисовка, загрузка ресурсов, файловая система, система кэширования и т.д.). Единственное исключение — звуки и музыка, они полностью относятся к Game.

Поскольку меня больше интересовал движок, особо я здесь не разбирался. Но в этом модуле видно больше опыта и организации: 15 файлов делят исходный код на понятные модули. В нём даже есть types.h (инициатор stdint.h ) для улучшения портируемости.

Читайте также:  Ipa файл для windows

Пара интересных моментов:

  • game.c — это монстр из 11 026 строк кода.
  • В menu.c есть 3000 строк со «switch case».
  • Большинство методов имеют параметры «void» и возвращают «void». Всё выполняется через глобальные переменные.
  • В наименованиях методов не используется camelCase или префикс NAMESPACE.
  • В модуле есть хороший парсер/лексический анализатор, хотя и значения токеновпередаются через десятичные значения вместо #define .

В целом эту часть кода легко читать и понимать.

Унаследованный исходный код

Глядя на бесконечное количество портов, порождённых Doom/Quake, я всегда удивлялся, почему так мало портов Duke Nukem 3D. Тот же вопрос возник, когда движок был портирован под OpenGL только после того, как Кен Силверман решил заняться этим самостоятельно.

Теперь, когда я посмотрел на код, рискну объяснить это во второй части этой статьи

Chocolate Duke Nukem 3D

Я обожаю этот движок и люблю игру, поэтому не мог оставить всё как есть: я создал Chocolate Duke Nukem 3D, порт «ванильного» исходного кода, пытаясь достичь таким образом двух целей:

  • Обучение: простота чтения/понимания и удобство портирования.
  • Достоверность: игровой процесс должен быть похожим на тот, который мы видели в 1996 году на наших 486-х.

Надеюсь, эта инициатива поможет унаследовать код. Самые важные модификации будут описаны во второй части статьи.

Внутренности движка Build

Build использовался в Duke Nukem 3D и многих других успешных играх, таких как Shadow Warrior и Blood. В момент выпуска 29 января 1996 года он уничтожил движок Doom инновационными возможностями:

  • Разрушаемым окружением
  • Наклонными полами и потолками
  • Зеркалами
  • Возможностью смотреть вверх и вниз
  • Способностью летать, ползать и плавать под водой
  • Воксельными объектами (появились позже в «Blood»)
  • Настоящим погружением в 3D (благодаря телепортам).

Корону у него отнял в июне 1996 года Quake, запущенный на мощных «Пентиумах»… но в течение нескольких лет Build обеспечивал высокое качество, свободу дизайнеров и, что важнее всего, хорошую скорость на большинстве компьютеров того времени.

Важнейшая концепция: система порталов

Большинство 3D-движков разделяло игровые карты с помощью двоичного разбиения пространства (Binary Space Partition) или октодерева (Octree). Doom, например, предварительно обрабатывал каждую карту затратным по времени методом (до 30 минут), в результате чего получалось BSP-дерево, позволявшее:

  • Сортировать стены
  • Определять положение
  • Обнаруживать столкновения.

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

На этой карте гейм-дизайнер нарисовал 5 секторов (сверху) и соединил их вместе, пометив стены как порталы (снизу).

В результате база данных мира Build стала до смешного простой: один массив для секторов и один массив для стен.

Ещё одно заблуждение относительно Build — он не выполняет испускание лучей: вершины сначала проецируются в пространство игрока, а затем генерируется столбец/расстояние из точки обзора.

Обзор рабочего цикла

Высокоуровневое описание процесса рендеринга кадра:

  1. Игровой модуль передаёт модулю движка сектор, с которого должен начаться рендеринг (обычно это сектор игрока, но может быть и сектор с зеркалом).
  2. Модуль движка обходит систему порталов и посещает интересующие секторы. В каждом посещённом секторе:
    • Стены группируются во множества, называемые группами («bunch»). Они сохраняются в стек.
    • Определяются спрайты, которые видимы в этом секторе, и сохраняются в стек.
  3. Группы обрабатываются в порядке от ближних к далёким: рендерятся сплошные стены и порталы.
  4. Рендеринг останавливается: ожидание, пока игровой модуль обновляет видимые спрайты.
  5. Рендерятся все спрайты и прозрачные стены в порядке от далёких к ближним.
  6. Переключаются буферы.

Вот каждый из этапов в коде:

Интересный факт: если вы изучаете код, то есть полностью развёрнутый цикл, который я использовал в качестве карты.

Интересный факт: почему метод переключения буферов называется nextpage() ? В 90-х радость программирования для VGA/VESA включала в себя реализацию двойной буферизации: две части видеопамяти выделялись и использовались по очереди. Каждая часть называлась «страницей» («page»). Одна часть использовалась модулем VGA CRT, а вторая обновлялась движком. Переключение буферов заключалось в использовании CRT следующей страницы («next page») заменой базового адреса. Гораздо подробнее можно почитать об этом в Главе 23 книги Майкла Абраша «Black Book of Graphic Programming: Bones and sinew».

Сегодня SDL упрощает эту работу простым флагом видеорежима SDL_DOUBLEBUF , но имя метода осталось как артефакт прошлого.

1. С чего начинать рендеринг?

Отсутствие BSP означает, что невозможно взять точку p(x,y) и пройти по узлам дерева, пока не достигнем сектора листа. В Build текущий сектор игрока нужно отслеживать после каждого обновления положения с помощью updatesector(int newX, int newY, int* lastKnownSectorID) . Игровой модуль вызывает этот метод модуля движка очень часто.

Наивная реализация updatesector сканировала бы линейно каждый сектор и каждый раз проверяла, находится ли p(x,y) внутри сектора S. Но updatesector оптимизирована поведенческим шаблоном:

  1. Записывая lastKnownSectorID , алгоритм полагает, что игрок переместился не очень далеко и начинает проверку с сектора lastKnownSectorID .
  2. Если пункт 1 выполнить не удалось, алгоритм проверяет с помощью порталов соседние lastKnownSectorID секторы.
  3. И, наконец, в наихудшем сценарии он проверяет все сектора линейным поиском.

На карте слева последним известным сектором положения игрока был сектор с идентификатором 1 : в зависимости от расстояния, на которое переместился игрок, updatesector выполняет проверку в следующем порядке:

  1. inside(x,y,1) (игрок переместился не так далеко, чтобы покинуть сектор).
  2. inside(x,y,0) (игрок слегка переместился в соседний сектор).
    inside(x,y,2)
  3. inside(x,y,0) (игрок сильно переместился: потенциально необходима проверка всех секторов игры).
    inside(x,y,1)
    inside(x,y,2)
    inside(x,y,3)
    inside(x,y,4)

Наихудший сценарий может быть довольно затратным. Но бóльшую часть времени игрок/снаряды перемещаются не очень далеко, и скорость игры остаётся высокой.

Подробности об inside

Inside — это примечательный по двум причинам метод:

  • Он может использовать только целые числа.
  • Он должен выполняться для секторов, которые могут быть вогнутыми.

Я подробно рассматриваю этот метод, потому что он отлично демонстрирует, как работает Build: с помощью старых добрых векторных произведений и XOR.

Эпоха вычислений с фиксированной запятой и вездесущие векторные произведения

Поскольку в большинстве компьютеров 90-х не было сопроцессора для чисел с плавающей точкой (FPU) (386SX, 386DX и 486SX), в Build использовались только целые числа.

В примере показана стена с конечными точками A и B: задача заключается в том, чтобы определить, находится точка слева или справа.

В Главе 61 книги Майкла Абраша «Black Book of Programming: Frame of Reference» эта задача решается простым скалярным произведением и сравнением.

Но в мире без операций с плавающей запятой задача решается векторным произведением.

Интересный факт: если задать в исходном коде Build строку поиска «float», то не найдётся ни одного совпадения.
Интересный факт: использование типа float популяризировал Quake, потому что он был предназначен для процессоров Pentium и их сопроцессоров для чисел с плавающей точкой.

Внутри вогнутого полигона

Узнав, как векторное произведение можно использовать для определения положения точки относительно стены, мы можем подробнее рассмотреть inside .

Пример с вогнутым полигоном и двумя точками: Point 1 и Point 2.

  • Point 1 считается находящейся снаружи.
  • Point 2 считается находящейся внутри.

«Современный» алгоритм для определения точки в полигоне (point-in-polygon, PIP) заключается в испускании луча слева и определении количества пересечённых сторон. При нечётном количестве точка находится внутри, при чётном — снаружи.

В Build используется вариация этого алгоритма: он считает количество рёбер на каждой стороне и комбинирует результаты с помощью XOR:

Интересный факт: движку Doom приходилось выполнять примерно такие же трюки в R_PointOnSide. В Quake использовались плоскости и операции с числами с плавающей запятой в Mod_PointInLeaf.

Интересный факт: если inside вам кажется трудным в чтении, советую изучить версию Chocolate Duke Nukem, в ней есть комментарии.

2. Портальные и непрозрачные стены

Начальный сектор передаётся движку Build игровым модулем. Рендеринг начинается с непрозрачных стен в drawrooms : два этапа, соединённые стеком.

  • Этап предварительной обработки заливает портальную систему (начиная с startingSectorID ) и сохраняет стены в стеке: scansector() .
  • Стек состоит из элементов «bunch».
  • Элементы стека передаются в метод рендерера: drawwalls() .

Что же такое «группа» (bunch)?

Группа — это множество стен, которые считаются «потенциально видимыми». Эти стены относятся к одному сектору и постоянно (соединенные точкой) направлены в сторону игрока.

Большинство стен в стеке будет отброшено, в результате только некоторые рендерятся на экране.

Примечание: «wall proxy» — это целое число, ссылающееся на стену в списке «потенциально видимых» стен. Массив pvWalls содержит ссылку на стену в базе данных мира, а также её координаты, повёрнутые/перемещённые в пространство игрока и экранное пространство.

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

Интересный факт: для пометки посещённых «секторов» процесс заливки использует массив. Этот массив должен очищаться перед каждым кадром. Для определения того, посещался ли сектор в текущем кадре, он не использует трюк с framenumber.

Интересный факт: в движке Doom для преобразования углов в столбцы экрана использовалась квантификация. В Build для преобразования вершин пространства мира в пространство игрока использовалась матрица cos/sin.

Читайте также:  Update realtek audio drivers для windows

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

Генерирование групп

Стены внутри сектора группируются в «группы» («bunches»). Вот рисунок для объяснения идеи:

На рисунке выше показаны что три сектора сгенерировали четыре группы:

  • Sector 1 сгенерировал одну группу, содержащую одну стену.
  • Sector 2 сгенерировал одну группу, содержащую три стены.
  • Sector 3 сгенерировал две группы, каждая из которых содержит по две стены.

Зачем вообще группировать стены в группы? Потому что в Build нет никакой структуры данных, позволяющей выполнять быструю сортировку. Он извлекает ближайшую группу с помощью процесса (O²), который был бы очень затратным, если бы выполнялся для каждой стены. Затраты ресурсов гораздо ниже, чем при выполнении для множества всех стен.

Использование групп

После заполнения стека групп движок начинает отрисовывать их, начиная от близких к далёким. Движок выбирает первую группу, которая не перекрыта другой группой (всегда есть хотя бы одна группа, удовлетворяющая этому условию):

Примечание: несмотря на название переменной, выбираемая группа не обязательно бывает ближайшей.

Объяснение принципа выбора, данное Кеном Силверманом:

Пусть есть 2 группы. Сначала мы проверяем, не перекрываются ли они в экранных x-координатах. Если не перекрываются, но условие перекрытия не нарушается и мы переходим к следующей паре групп. Для сравнения групп находим первую стену в каждой из групп, которая перекрывается в экранных x-координатах. Потом проводится проверка между стенами. Алгоритм сортировки стен следующий: находим стену, которую можно продолжить в бесконечность без пересечения с другой стеной. (ПРИМЕЧАНИЕ: если они обе пересекаются, то сектор неисправен, и следует ожидать «глюков» отрисовки!) Обе точки на другой (не продолженной) стене должны находиться по одну сторону продолженной стены. Если это происходит на той же стороне, что и точка обзора игрока, то другая стена находится перед ним, в противном же случае — наоборот

bunchfront — быстрый, сложный и несовершенный, поэтому Build дважды выполняет проверку перед отправкой результата рендереру. Это уродует код, но в результате мы получаем O(n) вместо O(n²).

Каждая выбранная группа отправляется drawalls(closest) рендерера: эта часть кода отрисовывает как можно больше стен/полов/потолков.

Визуализация стен/полов/потолков

Для понимания этой части важно уяснить, что всё рендерится вертикально: стены, пол и потолки.

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

Примечания: движок обычно использует массивы примитивных типов вместо массива struct.

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

Примечание: бóльшую часть времени массив отсечения обновляется только частично: порталы оставляют в нём «дыры».

Каждая стена в группе проецируется в экранное пространство, а затем:

    Если это сплошная стена:

  • Рендерится потолок, если он видим.
  • Рендерится пол, если он видим.
  • Рендерится стена, если она видима.
  • Целый столбец помечается как в массиве отсечения как перекрытый.

  • Если это портал:

    • Рендерится потолок, если он видим.
    • Рендерится пол, если он видим.
    • Движок «заглядывает» в следующий сектор:
    • Массив отсечения обновляется с учётом того, что было отрисовано.
  • Условие останова: этот цикл будет продолжаться, пока не будут обработаны все группы или пока все столбцы пикселей не будут помечены как выполненные.

    Это гораздо проще понять на примере, разбивающем сцену, например, знакомый всем зал:

    На карте порталы показаны красным, а сплошные стены — белым:

    Три стены первой группы проецируются в экранное пространство: на экран попадают только нижние части.

    Поэтому движок может рендерить пол вертикально:

    Затем движок «заглядывает» в соседние с каждой из трёх стен секторы: поскольку их знчение не -1 , эти стены являются порталами. Видя разницу между высотами полов, движок понимает, что надо отрисовывать для каждого из них уступ вверх («UP»):

    И это всё, что рендерится с первой группой. Теперь в экранное пространство проецируется вторая группа.

    И снова попадает только нижняя часть. Это значит, что движок может рендерить пол:

    Заглянув в следующий сектор и увидев самый длинный портал, движок может отрисовывать уступ вверх («STEP UP»). Однако второй портал в группе ведёт к более низкому сектору: уступ НЕ отрисовывается.

    Процесс повторяется. Вот видео, показывающее полную сцену:

    В результате отрисовки портала двери Build отрисовал уступ вверх и уступ вниз двумя разными текстурами. Как это возможно с помощью только одного picnum ?:

    Это возможно, потому что структура имеет » picnum «, это » overpicnum » для односторонних стен или стен с масками, и флаг, позволяющий «украсть» индекс нижней текстуры со стены противоположного сектора. Это был хак, позволивший сохранить маленький размер структуры сектора.

    Я скомпилировал в видео две другие сцены:

    С 0:00 до 0:08 : портал нижней линии тротуара использован для отрисовки вертикальной части пола.

    На 0:08 движок ищет уровень пола сектора после тротуара. Поскольку он поднимается вверх, отрисовывается портальная стена: рендеринг тротуара завершён.

    С 0:18 до 0:30: группа, состоящая из двух тротуаров слева используется для рендеринга огромного куска пола.

    Это интересная сцена, в которой появляется окно.

    В последнем видео показано окно. Вот подробности о том, как оно создаётся:

    Первая группа содержит четыре стены, которые при проецировании в экранное пространство позволяют отрисовать потолок и пол:

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

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

    Тот же процесс «заглядывания» выполняется и для пола. Поскольку он выше, то отрисовывается стена уступа вверх:

    И, наконец, обрабатывается последняя стена. Она не является порталом, поэтому отрисовываются полные столбцы пикселей.

    Интересный факт: поскольку стены отрисовываются вертикально, Build хранит текстуры в ОЗУ повёрнутыми на 90 градусов. Это значительно оптимизирует использование кэша.

    3. Пауза

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

    4. Рендеринг спрайтов

    После того, как игровой модуль завершит анимацию всех видимых спрайтов, Build начинает отрисовку: с дальнего к ближнему в drawmasks() .

    1. Вычисляется расстояние от точки обзора до каждого спрайта.
    2. Массив спрайтов сортируется алгоритмом Шелла
    3. Движок поочерёдно берёт данные из двух списков (один для спрайтов и один для прозрачных стен).
    4. После исчерпания одного списка движок пытается минимизировать ветвление и переключается на цикл, рендерящий только один тип: спрайты или стены.

    Профайлинг

    Запуск Duke Nukem 3D через отладчик «Instruments» натолкнул на мысль о том, на что тратятся циклы процессора:

    Неудивительно: бóльшая часть времени тратится на рендеринг непрозрачных стен и ожидание возможности переключения буфера (включена vsync).

    93% времени тратится на отрисовку сплошных стен. 6% отведено визуализации спрайтов/прозрачных стен.

    Несмотря на свою сложность, определение видимых поверхностей (Visible Surface Determination) занимает всего 0,1% этапа визуализации сплошных стен.

    Функции *scan — это интерфейс между движком и процедурами ассемблера:

    • wallscan() : стены
    • ceilscan() : потолки без наклона
    • florscan() : полы без наклона
    • parascan() : параллакс неба (использует внутри wallscan() )
    • grouscan() : наклонные потолки и полы — работает медленнее

    Комментарии Кена Силвермана:

    ceilscan() и florscan() сложны, потому что они преобразуют список вертикальных диапапзонов в список горизонтальных диапазонов. Именно для этого нужны все эти циклы while. Я сделал это, потому что накладывать текстуры на потолки и полы без наклона гораздо быстрее в горизонтальном направлении. Это критически важная оптимизация движка, которую вы, наверно, не заметили. Я видел похожие циклы while и в исходном коде Doom.

    Кен прислал мне скрипт evaldraw, span_v2h.kc, показывающий, как ceilscan() и florscan() преобразуют список вертикальных диапазонов в список горизонтальных диапазонов:

    displayrest взят из игрового модуля. Основные затраты здесь снова приходятся на отрисовку (оружия). Панель состояния не отрисовывается каждый кадр, она вставляется только при изменении счётчика боеприпасов.

    Интересные факты о VGA и VESA

    Благодаря X-Mode VGA большинство игроков запускало Build в разрешении 320×240. Но благодаря стандарту VESA движок также поддерживает разрешение Super-VGA. «Ванильные» исходники оснащены кодом VESA, обеспечивавшим портируемое определение разрешения и рендеринг.

    Ностальгирующие могут почитать о программировании для VESA в этом хорошем руководстве. Сегодня в коде остались только названия методов, например, getvalidvesamodes() .

    Звуковой движок

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

    Унаследованный код

    Код Build очень трудно читать. Я перечислил все причины этих сложностей на странице Duke Nukem 3D and Build engine: Source code issues and legacy.

    Рекомендуемое чтение

    Никакого. Займитесь лучше скалолазанием — это потрясающе!

    Источник

    Оцените статью