Dagon 0.40.0

Этот релиз ознаменовался серьезным рефакторингом постпроцессинга в движке: внесено множество оптимизаций и новых возможностей, а также появилась поддержка пользовательских фильтров (PostProcRenderer.addFilterPass). Возвращена поддержка автоэкспозиции, которая когда-то уже была реализована, но впоследствии удалена из-за архитектурных изменений в движке. Управляется параметрами hdr.autoexposure, hdr.keyValue, hdr.exposureAdaptationSpeed в render.conf. Добавлены эффекты виньетирования (vignette.enabled, vignette.strength, vignette.size, vignette.roundness, vignette.feathering) и film grain (filmGrain.enabled, filmGrain.colored). Реализован высококачественный фильтр повышения резкости с алгоритмом на основе FidelityFX CAS (sharpening.enabled, sharpening.strength). Добавлены новый тонмаппер Lottes (hdr.tonemapper: "Lottes"), новые параметры фильтра Depth of Field (dof.circleOfConfusion, dof.pentagonBokeh, dof.pentagonBokehFeather), улучшен фильтр шумоподавления SSAO — добавлена поддержка взвешивания на основе глубины, что устраняет гало-артефакты на близких расстояниях. Фильтр цветокоррекции теперь поддерживает изменение яркости, контраста и насыщенности (cc.brightness, cc.contrast, cc.saturation). Также можно напрямую задать 4×4 матрицу цветокоррекции (cc.colorMatrix). Если используется LUT, эти параметры игнорируются.

Улучшен воркфлоу таблиц цветокоррекции (LUT). Добавлено новое свойство TextureAsset.lutFormat, посредством которого загрузчик текстур понимает, что нужно конвертировать двумерную таблицу в 3D-текстуру. Поддерживаются два формата — LUTFormat.Hald и LUTFormat.GPUImage. Свойство TextureAsset.loadAs3D удалено, вместо него теперь надо задавать TextureAsset.lutFormat = LUTFormat.Hald;. Дефолтная таблица формата GPUImage (загружаемая опцией lut.file) теперь автоматически конвертируется в 3D-текстуру. Если вы загружаете GPUImage LUT вручную, то можно ее не конвертировать, но отныне рекомендуется делать это для более эффективного сэмплинга в шейдере.

Добавлен опциональный вывод в честный sRGB вместо обычного Gamma 2.2. Теперь можно задать цветовой профиль вывода при помощи опции gl.outputColorProfile в settings.conf. Возможные значения (строковые): "Gamma22", "sRGB".

Реализована поддержка глобальных определений макропроцессора GLSL (функция globalShaderDefine в dagon.graphics.shader). Чтобы их использовать в шейдерах, нужно добавить виртуальный инклюд #include <dagon>.

Добавлена поддержка сохранения в DDS кубических карт, 3D-текстур и RGTC-текстур. Появилась новая функция downloadTexture для выгрузки текстур любого формата из видеопамяти.

Появился новый тип событий EventType.KeyboardLayoutChange и соответствующий метод-обработчик onKeyboardLayoutChange. Это событие возникает, когда пользователь переключает раскладку клавиатуры.

Повышение резкости

Добавил в Dagon фильтр повышения резкости на основе FidelityFX CAS. Его можно включить свойством sharpening.enabled в render.conf, свойство sharpening.strength управляет силой эффекта. Вкупе с анизотропной фильтрацией это значительно повышает качество рендера. На скриншоте разница особенно заметна на золотых узорах гобеленов и текстуре каменной кладки.

Dagon 0.39.0

Новая версия движка. Добавил возможность загружать кастомные курсоры и заменять ими системные курсоры в приложении (методы Application.loadCursor, Application.replaceCursor). Появилась поддержка многомониторных конфигураций — теперь можно задать индекс монитора для создания игрового окна (опция window.display в settings.conf). Добавлены новые свойства класса Application: displayCount, displayIndex, displayWidth, displayHeight, desktopWidth, desktopHeight, refreshRate, framebufferFormat.

В модуль dagon.graphics.shape добавлены новые геометрические тела: ShapeCapsule (капсула), ShapeTorus (тор).

Появилась Поддержка uniform-массивов — шаблонный класс ShaderParameterArray и метод Shader.createParameterArray. Методы Shader.setParameter, Shader.setParameterRef, Shader.setParameterCallback, Shader.setParameterSubroutine, Shader.getParameterValue помечены как deprecated. Рекомендуется работать с объектами параметров напрямую.

Добавлена поддержка несжатых текстур RGB8 и RGBA8 в экспортер DDS, а также несжатых RGB8 в загрузчик DDS. Реализована перегрузка функции loadImageViaSDLImage, которая возвращает SDL_Surface*.

Перлы из сабреддита /r/vulkan

К Vulkan я испытываю если не неприязнь, то во всяком случае изрядный скепсис. Это API для машин, а не для людей. Писать на нем напрямую — это ад, и веских причин пытать себя вулкановскими ужасами (во всяком случае, в инди-разработке) я за эти десять лет так и не увидел. Оптимизация CPU-bound частей рендера? Вы не Epic Games, чтобы этим заниматься — ресурсов не хватит. DLSS, трассировка лучей? В реальности все эти навороты в играх отключают первым делом, чтобы играть, а не смотреть слайдшоу, ибо видеокарты у большинства далеко не топовые.

Но вот что забавно: вулканисты сами признают, что использовать Vulkan необязательно! Если не верите, откройте Reddit. Вот что я там нашел:

pls use vk-bootstrap, dynamic rendering, VMA in big 2026. Don’t do raw vulkan. You will lose motivation sooner.

То есть, без разнообразных обвязок и прибамбасов писать на Vulkan принципиально не рекомендуется! Это прям классно — напомнило времена GLU, GLUT и тому подобного. Я и сам пробовал много всяких компромиссных вариантов — вкатывался в WebGPU, щупал LLGL и GPU API в SDL3, но везде одна и та же жопа в разных ракурсах: нужны дополнительные инструменты, как минимум для компиляции шейдеров и SPIR-V рефлексии. Оверхед по расходу памяти от всех этих обвязок немаленький, в WebGPU вообще память течет — привет растоманам. И я уж молчу про то, что обвязки систематически ломают обратную совместимость, так что писать на них — то еще удовольствие.

А вот это вообще анекдот:

Your options are basically:
— Learn Vulkan, but use AI to fill in the boilerplate.
— Use CUDA instead of Vulkan.

Без ИИ сегодня, конечно, вообще никуда 😂 А графическая разработка — такая уж область, ChatGPT ногу сломит. Ну и наконец:

OpenGL is perfectly viable in 2026 for hobby programmers and you’ll probably even get better performance out of it than not knowing how to use Vulkan and using it anyway. Hardware support is also completely fine. If you want to learn Vulkan, go do it. If you don’t, there’s better alternatives.

Занавес. Directed by Robert B. Weide.

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);

Ловим необработанные исключения под Windows

Обработка исключений — это всегда скучно и многословно, никому не хочется загромождать свой код вездесущими try/catch. Кроме того, в D обработка исключений на уровне языка не работает с SEH-исключениями под x86_64, что сильно усложняет отлов багов, связанных с доступом по невалидному указателю — приложение просто падает молча, что не соответствует принципу «fail loudly». Но оказалось, что есть относительно простой способ решения этой проблемы.

(далее…)

Dagon 0.37.0

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

Всемогущий alias

Русский перевод моей статьи «Almighty Alias». Оригинал опубликован на Medium.

alias — мое любимое ключевое слово в D! Не перестаю удивляться тому, сколько разных вещей оно делает. В D почти ко всему можно объявить псевдоним, и есть фичи, которые работают исключительно при помощи alias.

(далее…)

Обновления

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

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

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