Dagon 0.26.0

На днях вышла новая версия движка! Как я уже писал ранее, в этой версии все загрузчики ресурсов в Dagon используют единую виртуальную файловую систему — Application.vfs. В связи с этим класс VirtualFileSystem был значительно актуализирован и расширен. В частности, теперь движок из коробки поддерживает загрузку ресурсов из папки с данными (C:\Users\AppData\Roaming\<appDataFolder> под Windows, где <appDataFolder> — кастомное имя папки, которое указывается при создании приложения Dagon). Кроме того, главный конфиг приложения (ранее Game.config) переехал в класс Application. Появился новый метод Application.showConsoleWindow для переключения видимости окна консоли под Windows.

В EventManager наконец-то доведена до ума проверка однократного нажатия и отпускания клавиш/кнопок мыши/кнопок контроллера (EventManager.keyDown, EventManager.keyUp и т.д.). Эта функциональность добавляет небольшой оверхед, поэтому она по умолчанию отключена — нужно ее включать свойством EventManager.trackUpDownState. Как следствие, InputManager.getButtonUp и InputManager.getButtonDown теперь также работают корректно. Добавлено свойство EventManager.application, чтобы можно было получить доступ к объекту приложения из менеджера событий.

Добавлен новый аппаратно-ускоряемый генератор кубических карт — функция dagon.graphics.texproc.generateCubemap, эффективная замена методу Texture.createFromEquirectangularMap. Эта функция конвертирует равнопромежуточные карты окружения в кубические, что позволяет избежать некоторых неприятных артефактов первых. Благодаря переносу на GPU, теперь эта процедура выполняется очень быстро. Данный компонент будет развиваться и дальше — в следующих версиях будет поддержка префильтрации, о которой я писал в предыдущем посте.

Предрассчитанная таблица BRDF LUT теперь поставляется вместе с движком в папке data/__internal/textures/brdf.dds. Эта текстура загружается автоматически и доступна как DeferredRenderer.brdf. В случае использования отложенного рендера, рекомендуется активировать ее следующим образом:

environment.ambientBRDF = game.deferredRenderer.brdf;

Это нужно для физически обоснованного расчета зеркальных отражений от карты окружения. Таблица хранит значения функции Смита для различных сочетаний шероховатости и углов падения.

GLTFPose и GLTFBlendedPose теперь обновляют матрицы трансформации объектов Entity, ассоциированных с костями glTF. Это позволяет, например, использовать Entity.positionAbsolute для получения позиции кости в мировом пространстве.

Добавлен новый модуль dagon.extra.verlet с реализацией position-based динамики для симуляции веревок и цепей.

Префильтрация кубических карт

В дополнение к простому конвертеру из равнопромежуточных карт окружения в кубические карты, в Dagon появилась поддержка предварительной фильтрации (prefiltering) — то есть, свертки кубических карт с использованием GGX BRDF под различные значения шероховатости. Результаты свертки сохраняются в mip-уровнях. Этот процесс является одной из ключевых оптимизаций PBR, поскольку избавляет от необходимости вычислять интеграл облученности в реальном времени. Префильтрация осуществляется очень быстро на GPU, поэтому ее, в принципе, можно делать каждый раз при запуске приложения (но лучше, конечно, однократно с кэшированием в файл — скоро добавлю и такую возможность). Преимуществом является то, что теперь для этого необязательно использовать сторонние утилиты типа IBLBaker — движок все делает сам.

Реализация основана на классическом методе (выборка по последовательности ван дер Корпута-Хаммерсли), описанном в статье «Real Shading in Unreal Engine 4» (Брайан Карис, Epic Games, SIGGRAPH 2013).

Виртуальная файловая система

В Dagon уже достаточно давно существовала поддержка VFS, но до сих пор все загрузчики ресурсов использовали отдельные объекты VirtualFileSystem, поэтому не было простой возможности монтировать общие для всей логики движка пути. Все изменится в грядущем Dagon 0.26, где будет единая VFS на все случаи жизни — Application.vfs. Пользовательский API при этом останется без изменений.

VFS позволяет хранить ресурсы игры в различных папках (и даже в архивах), предоставляя унифицированный интерфейс для доступа к ним. По умолчанию в Dagon теперь монтируются рабочая папка игры и папка с данными (C:\Users\AppData\Roaming\<appDataFolder> под Windows, где <appDataFolder> — кастомное имя папки). Последний примонтированный источник является наиболее приоритетным — то есть, в данном случае файл будет сначала искаться в appDataFolder, а потом — в рабочей папке. Преимуществом такого подхода является упрощение моддинга, возможность замены любого ресурса без риска сломать оригинальную игру, вплоть до создания тотальных конверсий.

Шоурил 2025

Выпустил на YouTube-канале небольшое обзорное видео самых интересных новых возможностей Dagon:

Dagon 0.25.0

Вышла очередная версия движка! Наиболее интересным нововведением является расширение dagon:video, о котором я писал ранее — теперь в играх можно воспроизводить видео при помощи библиотеки libVLC. Видеопоток декодируется в текстуру, которую можно применить к любому материалу. Для полноэкранного отображения видео предусмотрен виджет FullscreenMediaView.

Наконец-то добавил в упрощенный рендер поддержку точечных и конусных источников света. Поддерживается до 8 источников света на слой, их нужно добавлять методом SimpleRenderPass.addLight. Также в упрощенном рендере появилась поддержка cel-шейдинга — управляется свойствами Material.celShading и Material.rimLight. В deferred-рендере эти свойства ни на что не влияют.

Появилась поддежка uniform-блоков в шейдерах. Вы можете создать массив uniform-структур при помощи объекта UniformBlockParameter. Поля структуры должны соответствовать требованиям std140.

Реализован MaterialAsset — ресурс описания материала, основанный на том же синтаксисе, что и конфигурационные файлы. Кстати, в файлах *.conf теперь поддерживаются матрицы 4×4 и 3×3 (фактически они являются массивами из 16 или 9 числовых значений, которые можно интерпретировать в приложении как матрицы с построчным расположением элементов).

Из мелочей: поддержка Entity.opacity в HUD-проходе, поддержка анимации для свойства Entity.opacity, поддержка Material.emissionEnergy в шейдере Sky, свойство TextureAsset.loaded.

libVLC и видеотекстуры

Я давно искал удобное решение для воспроизведения видео в играх, и вот, наконец, оно найдено — libVLC, библиотека, на которой основан всеми любимый плеер VLC. В отличие от FFMPEG, это высокоуровневый API, который позволяет буквально в несколько строк добавить видеоплеер в любое окно по HWND (или X window ID под Linux). Но самое интересное, конечно, декодировать видео во внеэкранный буфер, чтобы потом передать его в OpenGL-текстуру — libVLC это также позволяет с минимальными телодвижениями. Я уже добавил в репозиторий Dagon экспериментальное расширение dagon:video, которое предоставляет класс Video, обертку над libvlc_media_t* и libvlc_media_player_t*. Использовать его очень просто — сначала создается VideoManager, общий для всего приложения (лучше хранить его в классе, наследующем от Game):

VideoManager videoManager = New!VideoManager(this);

Затем, уже в сцене, создается источник видео:

Video video = New!Video(videoManager, 1920, 1080, assetManager);
video.open("media/video.mp4");

auto videoMaterial = addMaterial();
videoMaterial.baseColorTexture = video.texture;
videoMaterial.alphaTestThreshold = 0.0f;

video.play();

Можно использовать видеотекстуру для любых целей — показать заставку в начале игры, натянув на screen-aligned плоскость, или применить к мешу для создания внутриигрового экрана. Можно даже воспроизводить 360-градусные ролики в равнопромежуточной проекции для отображения на панорамном фоне.

Dagon 0.24.0

Выпустил новую версию движка. Основное нововведение — рендеринг текста теперь является частью ядра движка в качестве модуля dagon.graphics.font (таким образом, FreeType становится зависимостью ядра). Расширение dagon:ftfont удалено. В связи с этим я решил добавить в Dagon встроенный простой GUI. В данный момент поддерживаются перетаскиваемые окна, вывод многострочного текста (TextView), строка ввода (TextInput) и консоль (Console). GUI-тулкит встроен в объект Scene — доступен как свойство Scene.ui.

Добавлен менеджер шрифтов (Application.fontManager). Он загружает шрифты по умолчанию (Liberation Sans и Liberation Mono, которые прилагаются к движку) и позволяет создавать новые.
Добавлена базовая поддержка библиотеки Assimp (расширение dagon:assimp). Поддерживаются меши, узлы и некоторые свойства материалов (диффузный цвет, текстуры).

Также реализована возможность изменить системный курсор мыши методом Application.setCursor. Добавлена поддержка логирования в буфер.

Встроенный UI в Dagon

Наконец-то дошли руки начать пилить свой уютный UI-тулкит! Убийцу ImGui я, конечно, не планирую — это будет набор базовых виджетов для добавления в игру простых отладочных инструментов. Уже готовы окна и TextView — на скриншоте ниже демонстрируется вывод лога приложения.

Обновления

Dagon 0.23.1

Небольшое обновление Dagon 0.23. Добавлена поддержка переключения отдельных рендер-таргетов в PassTerrain — то есть, для материалов ландшафта работают свойства outputColor, outputNormal и др. Движок теперь использует dlib 1.3.2. Добавлены новые уроки — 9, 13 и 15.

К следующему релизу готовлю поддержку Assimp, о которой уже писал, а также перенос расширения dagon:ftfont в ядро движка, что позволит реализовать различные встроенные UI-компоненты.

BindbC-Assimp

Биндинг к Assimp 5 размещен на GitHub и доступен в качестве DUB-пакета. К сожалению, название bindbc-assimp занято заброшенным и несуществующим ныне проектом, поэтому пришлось зарегать как bindbc-assimp5.

Оптимизация блога

Я настроил объектный кэш на основе Redis, а также добавил HTML-кэш и заголовок Cache-Control, что заметно ускорило загрузку страниц блога. Было исправлено множество мелких проблем верстки. Все архивные игры теперь размещены на одном сервере с блогом.

Тема, которую я использую, теперь также доступна на GitHub. Это форк WPEX Blogger 1.2 от WPExplorer, в котором я внес исправления для совместимости с PHP 8, исправил поиск в мобильном меню, добавил новые переводы на русский, а также внес патч, исправляющий совместимость с плагином Code Syntax Block.

Поддержка Assimp

Библиотека Assimp — относительно тяжеловесное, но самое функциональное решение для загрузки 3D-моделей. У меня наконец-то дошли руки добавить поддержку Assimp 5+ в Dagon как расширение dagon:assimp, благодаря чему можно будет использовать в движке модели форматов FBX, Collada, 3DS и многих других. Пока загружаются только меши, но в планах добавить поддержку материалов, узлов и анимации.

Перед загрузкой модели можно задать кастомные флаги постпроцессора:

AssimpAsset aModel;

override void beforeLoad()
{
    aModel = this.addAssimpAsset("assets/cacodemon.fbx");
    aModel.loaderOption =
        aiPostProcessSteps.Triangulate | aiPostProcessSteps.FlipUVs;
}

После этого можно использовать меши из массива aModel.meshes для рендеринга:

auto e = addEntity();
e.drawable = aModel.meshes[0];