Dagon 0.38.0

Очередной релиз. Главное нововведение — это модуль dagon.core.dxt, быстрый компрессор текстур в DXT1/DXT5 (D-порт библиотеки RygsDXTc, о котором писал ранее). Текстуру теперь можно сжать после загрузки при помощи свойства TextureAsset.compress. Также реализована функция dagon.resource.dds.saveDDS для сохранения сжатых текстур в DDS. Добавлено новое свойство TextureAsset.assetManager. Добавлена поддержка дополнительных форматов SDL_Image в структуре ImageFileFormat, а именно GIF, QOI, PNM, XCF, XPM, PCX, LBM.

Добавлены новые опции settings.conf для глобального управления анизотропной фильтрацией текстур: gl.anisotropicFiltering и gl.defaultTextureAnisotropy. По умолчанию анизотропная фильтрация отключена.

Добавлен новый оператор тональной компрессии Uchimura.

Реализована обработка SEH-исключений под Windows с трассировкой стека в отладочных сборках (dagon.core.crashhandler).

Добавлена поддержка API вибрации (Haptic API) SDL (GameInputDevice.haptic), который, впрочем, на практике является экзотикой — далеко не все устройства с ним работают. Для большинства контроллеров в SDL поддерживается только Rumble API.

Добавлена функция dagon.core.dialogs.showMessage для графического вывода сообщений.

Если в системе не найдена библиотека Wintab, движок теперь логирует предупреждение вместо ошибки.

В расширении dagon:audio исправлены сигнатуры некоторых функций SoLoud, добавлена перегрузка метода AudioManager.createSound для создания звуков из буферов в памяти.

Исправлены некоторые важные баги в различных компонентах движка, а также ошибки компиляции под x86.

window.hiDPI теперь включен в дефолтном settings.conf.

RygsDXTc и сжатие текстур на лету

Очередная часть Марлезонского балета с компрессией текстур. Я долго думал, делать или не делать в движке сжатие в DXT, и ответ пришел в виде проекта RygsDXTc, быстрого компрессора DXT1/DXT5. Причем написанного не кем-нибудь, а самим Фабианом Гизеном aka ryg из легендарного Farbrausch!

Залипнув на вечер, я портировал на D эту тысячу строк зубодробительного C-кода, под завязку набитого черной магией целочисленной арифметики, и вот результат — в Dagon теперь можно простым переключением свойства отправлять текстуры в видеопамять в сжатом виде:

aTexture = addTextureAsset("data/input.png");
aTexture.compress = true;
aTexture.generateMipmaps = true;

При включенном generateMipmaps перед сжатием будут сгенерированы мип-уровни. Полноценно поддерживаются NPOT-текстуры. При этом оверхед на все про все ничтожный — libktx при транскодировании из Basis Universal и то срабатывает дольше.

Если задать перед загрузкой aTexture.persistent = true, то ассет сохранит исходный TextureBuffer в памяти, и вы сможете сохранить сжатую текстуру в DDS:

auto outputStrm = game.vfs.stdfs.openForOutput("out.dds");
saveDDS(outputStrm, &aTexture.buffer);
Delete(outputStrm);

Dagon 0.37.0

Вышла новая версия движка. Основное нововведение — поддержка объемных конусных источников света, о которых я ранее писал тут. В conf-файлах появилась поддержка комментариев (строки, начинающиеся с //) и булевых значений (true/false). Добавлен простой кинематический движок проверки столкновений (dagon.collision.collision), который лучше всего подходит для 3D-платформеров и квестов. Добавлен новый модуль dagon.ui.axes — отрисовка осей для 3D-манипуляторов. В данный момент реализован только один класс осей, TranslationAxes. Исправлена ошибка конфликта сэмплеров под AMD для некоторых шейдеров. Добавлена перегрузка метода Application.takeScreenshot для снятия скриншота в текстуру. Dagon теперь использует dlib 1.4.1.

Обновления

Продолжаю улучшать объемное рассеивание света, появившееся в Dagon 0.34.0 — на днях добавил его поддержку для конусных источников света. Теперь можно создавать эффекты прожекторов и фонарей.

Обновления библиотек:

  • dlib 1.4.1 — небольшое обновление dlib, в котором исправлен сеттер OBB.center;
  • bindbc-wgpu 0.27.0 — синхронизация с wgpu-native 27.

Chillwave Drive — новое видео

Выложил ролик с обновленной демкой автомобильной физики. Скачать свежую сборку можно на GitHub и на GameJolt.

YouTube, конечно, замедляют/блокируют, но я не собираюсь от него отказываться и переходить на другие видеохостинги — VK Video неудобный до жути, да и аудитория там не моя совсем.

Итоги 2025 года

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

  • Перенес почти все свои онлайн-ресурсы на новый сервер. Блог переехал на новый домен и был переименован в PixelPerfect Blog. Заодно я добавил некоторые оптимизации, за счет которых он теперь работает заметно быстрее;
  • Выпустил множество версий Dagon, от 0.19 до 0.36. Я перешел на новый итеративный принцип обновлений: теперь релизы выходят по мере добавления небольших наборов фич, вместо того, чтобы по полгода накапливать много изменений. В этом году движок был очень серьезно обновлен, перечислю тут лишь наиболее важное.
    • Состоялся переход на OpenGL 4.3;
    • Добавлена поддержка вычислительных шейдеров;
    • Появилась поддержка GPU-скиннинга и анимированных моделей glTF;
    • Реализована поддержка HiDPI;
    • Реализовано расширение для работы с устройствами виртуальной реальности посредством OpenVR;
    • В систему событий добавлена многопоточность с асинхронным обменом сообщениями между потоками;
    • Улучшена система загрузки текстур: изображения теперь загружаются через библиотеку SDL2_Image, что обеспечивает поддержку новых форматов — WebP, AVIF, SVG и многих других. Также реализована поддержка текстур в формате KTX/KTX2 с транскодированием из Basis Universal в различные профили аппаратного сжатия. Добавлена поддержка анизотропной фильтрации текстур;
    • Встроенный звуковой движок на основе SoLoud;
    • Поддержка видео на основе libVLC;
    • Поддержка теней для позиционных источников света (PSM и DPSM);
    • Объемное рассеивание для позиционных источников света;
    • Префильтрация кубических карт;
    • Бокс-проекция для зондов окружения;
    • Упрощенный рендер SimpleRenderer для казуальных игр и ретро-графики;
    • Шейдер океана;
    • Шейдер луж для ландшафта;
    • Поддержка Matcap-проекций для текстур;
    • Встроенная система проверки столкновений;
    • Логгер;
    • Простой GUI-тулкит;
    • Поддержка нескольких игровых контроллеров;
    • Ввод с Wintab-совместимых графических планшетов с учетом силы нажатия;
    • Поддержка локализации приложений;
    • Обновился сайт Dagon. Также у проекта наконец-то появилась онлайн-документация.
  • Выпустил dlib 1.3.1, 1.3.2, 1.3.3 и 1.4.0;
  • Написал биндинги к Vulkan, GLSLang, SPIRV-Cross, PhysFS. Все мои биндинги теперь живут в GitHub-организации DLangGamedev;
  • Значительно обновил Chillwave Drive, демку физики автомобиля;
  • Начал работу над GScript3, третьей версией моего скриптового языка;
  • Форкнул Programmer’s Notepad, мой любимый текстовый редактор под Windows, и выпустил три новые версии, 2.5, 2.6 и 2.7, с несколькими важными изменениями по сравнению с оригиналом;
  • Завершил работу над Xtreme3D 4.0.

Ну и, конечно, мой личный список интересных событий в мире D, Open Source и IT в целом:

  • D используется в NASA! В этом году стало известно, что ПО для сбора данных в рамках миссии TRACERS было написано на D;
  • D отметили в списке 10 самых быстрых языков программирования;
  • Выход демо-версии The Art of Reflection, новой инди-игры на D;
  • Выход в ранний доступ InZOI, next-gen симулятора жизни с реалистичной графикой — это первый в истории серьезный конкурент серии The Sims. Несмотря на сыроватый геймплей, игра поражает технологическим уровнем, особенно возможностями встроенных нейросетей для генерации моделей;
  • GreenSock Animation Platform, самый мощный фреймворк браузерной анимации, стал полностью бесплатным. Я использую GSAP во всех своих коммерческих браузерных играх, так что новость для меня весьма радостная.

Dagon 0.36.0

Вышла новая версия движка — скорее всего, это последний релиз в 2025 году.

Добавлен новый тип событий EventType.HardwareSpecific для поддержки кастомных устройств ввода. Это событие не имеет определенной спецификации — данные события зависят от типа устройства. Обработчик события, onHardwareSpecificEvent, принимает индекс устройства, пользовательский код и непрозрачный указатель void*, по которому могут быть любые данные.

Добавлен EventManager.tmpHeap — арена-аллокатор для короткоживущих объектов (строк, массивов и структур, создаваемых для событий). Он сбрасывается, когда обработаны все пользовательские события.

EventDispatcher.onUserEvent теперь принимает вторым параметром указатель void* для пользовательских данных.

Реализован новый класс приложений BaseGame, который не включает рендер, но включает управление сценой. Game теперь наследует от него. Renderer теперь принимает объект Application в конструкторе для потенциально более глубокой интеграции рендера с приложением.

Добавлено новое расширение dagon:openvr, реализующее базовую поддержку гарнитур виртуальной реальности через API OpenVR. Поддерживается синхронизация с HMD и отправка текстур для вывода. К сожалению, стандартный рендер-пайплайн Dagon в настоящее время несовместим с VR, он для этого нуждается в серьезной переделке. Для тестов в расширении реализован простейший StereoRenderer. Подробности о том, как работать с VR, вскоре будут в отдельном посте.

Обновления

Dagon 0.35.0

Вышла новая версия движка, в которой добавлена поддержка таймеров (Application.setTimer и событие Timer) и новый модуль dagon.core.sysinfo, предоставляющий базовую информацию об аппаратно-программной платформе, на которой запущено приложение. Исправлен забагованный метод Properties.serialize, реализована поддержка текстур в формате WebP в загрузчике glTF (расширение EXT_texture_webp для текстур), добавлена поддержка Entity.blurMask в режиме прямого рендеринга. Объект NewtonMeshShape в расширении dagon:newton теперь можно создавать с передачей матрицы трансформации, которая применяется ко всем вершинам меша. Также добавлен Dagon Platform — комплект для разработки игр под Dagon на языке GScript3, о нем я расскажу подробнее в одном из следующих постов.

Chillwave Drive 0.2.0

Демка автомобильной физики значительно обновлена: улучшена графика, модель машины заменена на McLaren GT, исправлено множество мелких недочетов в симуляторе, благодаря чему демка теперь адекватно поддерживает заднеприводные авто, а также устранен баг в модели колес, который создавал лишнюю боковую силу в некоторых ситуациях. Я решил развивать Chillwave Drive в качестве полноценной игры, в связи с чем создал соответствующую страничку на сайте GameJolt. Вероятнее всего, это будет симкейд для расслабляющего вождения, в котором можно добавлять собственные машины, настраивать окружение и т.д.

Dagon 0.34.0

Очередной релиз движка. Добавлена поддержка нескольких контроллеров (до 4 включительно). Методы-обработчики событий контроллера в EventListener теперь принимают индекс устройства в качестве первого аргумента. Индексы начинаются с нуля, устройства добавляются в порядке их подключения в системе. EventListener.onControllerAdd теперь принимает GameInputDeviceType в качестве второго аргумента.

Обновлен менеджер ввода. Символ + в клавишных биндингах input.conf заменен на символ _ (то есть, теперь вместоright+ctrl нужно писать right_ctrl). Добавлены символические имена для биндингов мыши (в input.conf): mb_left, mb_middle, mb_right, mb_x1, mb_x2, ma_x, ma_y.

Приложение теперь автоматически определяет разрешение монитора в полноэкранном режиме, если windowWidth и windowHeight указаны как 0. Добавлена поддержка безрамочных окон. Добавлены новые опции settins.conf: localePath, window.maximized, window.minimized, window.borderless, fullscreenWindowed. В режиме fullscreenWindowed размер окна игнорируется, создается безрамочное окно размером с весь экран, как раньше с указанием нулевых windowWidth и windowHeight в оконном режиме.

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

Исправлен и расширен класс LoadingScreen — добавлена поддержка HiDPI и фонового изображения.

Рассеивание для позиционных источников света

Добавил в Dagon фичу, которая редко встречается даже в AAA-движках — поддержку изотропного объемного рассеивания для позиционных источников света. До этого уже были т. н. «лучи Бога» для направленного света — более тяжелый анизотропный эффект, основанный на приближенной физике рассеивания света аэрозолями. Теперь, выставив light.scatteringEnable = true для любого источника света, можно сделать «свечение в тумане». Это похоже на постэффект glow, но отличается тем, что объемный свет рассчитывается геометрически, в трехмерном пространстве — поэтому, если самого источника света нет в кадре, свечение все равно видно.

Сочетанием обоих эффектов можно добиться приятной атмосферности в ночных сценах:

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

game.deferred.passLight.volumetricScatteringEnabled = true;