Dagon 0.18

Выпустил новую версию Dagon. В загрузчике OBJ наконец-то появилась поддержка групп — если в файле присутствуют группы, они будут доступны через свойство OBJAsset.groupMesh, так что вы можете использовать их в качестве отдельных мешей вместо единого OBJAsset.mesh. Также загрузчик теперь не падает на моделях с N-гонами, а выводит предупреждение, что они не поддерживаются.

Добавлен новый экстра-шейдер dagon.extra.starfieldsky — ночное небо со звездами. Он представляет собой улучшенную версию шейдера звездного неба из демки с планетой. Основное нововведение — поддержка мерцания звезд.

Слегка переделан NewtonCharacterComponent: появился новый параметр радиуса. Логика теперь следующая: контроллер персонажа, как и прежде, представлен двумя Newton-сферами, но их радиус теперь задается пользователем, а не вычисляется автоматически. Сферы располагаются сверху и снизу от барицентра на расстояниях, которые вычисляются исходя из радиуса и роста персонажа.

В dagon:iqm появились новые свойства для анимированных моделей: Actor.looping (зацикленность), Actor.state.finished (индикатор завершения текущей анимации). Исправлен баг с фейсгруппами при загрузке некоторых IQM.

Slang — универсальный шейдерный язык

Что выглядит читабельнее? Это:

struct VertexOutput
{
    @builtin(position) position: vec4<f32>,
    @location(0) fragmentPosition: vec4<f32>
};

@vertex
fn vs_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput
{
    let x = f32(i32(vertexIndex) - 1);
    let y = f32(i32(vertexIndex & 1u) * 2 - 1);
    var output: VertexOutput;
    output.position = vec4<f32>(x * 0.5, y * 0.5, 0.0, 1.0);
    output.fragmentPosition = 0.5 * (vec4<f32>(x, y, 0.0, 1.0) + 1.0);
    return output;
}

…или это:

struct VertexOutput
{
    float4 position: SV_Position;
    float4 fragmentPosition;
};

[shader("vertex")]
VertexOutput vertexMain(uint vertexIndex: SV_VertexID)
{
    let x = float(int(vertexIndex) - 1);
    let y = float(int(vertexIndex & 1u) * 2 - 1);
    VertexOutput output;
    output.position = float4(x * 0.5, y * 0.5, 0.0, 1.0);
    output.fragmentPosition = 0.5 * (float4(x, y, 0.0, 1.0) + 1.0);
    return output;
}

Второй листинг, на мой взгляд, выигрывает сравнение. Это код на Slang, HLSL-подобном языке, который позиционируется в качестве платформонезависимой основы для написания одних и тех же шейдеров под любые графические API, включая D3D12, Vulkan, Metal, OpenGL, а с недавних пор и WebGPU. Идея, конечно, не новая — если вы писали шейдеры в нулевые, то, наверное, помните Cg от NVIDIA — но с со времен попыток написать универсальный компилятор в низкоуровневые шейдерные языки утекло немало воды и сменилось несколько поколений графического железа. Сейчас, в эпоху Vulkan и SPIR-V, кросс-компиляция шейдеров актуальна как никогда: старичок GLSL уже сдает позиции, для новых стандартов создаются новые языки — индустрия переживает очередной этап фрагментации.

Я уже писал о своих впечатлениях от WGSL, встроенного шейдерного языка WebGPU, и многие его конструкции мне до сих кажутся спорными и неудобными. Особенно бесят типы вида vec4<f32>. Не так давно поддержка WGSL была добавлена в компилятор Slang, в связи с чем я теперь всерьез рассматриваю этот язык как основной для создания графического движка на WebGPU.

Главная киллер-фича Slang — это, конечно, модули. Причем, что интересно, есть и препроцессор а ля C с директивами #include, #ifdef и др. От HLSL и GLSL язык выгодно отличается большим набором фич, присущих современным высокоуровневым языкам: поддержкой вывода типов, пространств имен, функций-членов структур (с неизменяемым по умолчанию неявным this — по-моему, отличная идея!), а также конструкторов, геттеров/сеттеров и даже перегрузки операторов. Есть дженерики, интерфейсы, кортежи. Интересен тип Optional, который дополняет любой другой тип поддержкой значения none — чтобы можно было указать отсутствие какого-либо значения. Для SPIR-V и CUDA в языке есть ограниченная поддержка указателей. Очень полезный инструмент — декоратор ForceInline, который заменяет вызов функции подстановкой ее кода. Наконец, в языке есть автоматическое дифференцирование, которое используется в задачах машинного обучения.

Старую как мир проблему некоммутативности умножения матриц и векторов в Slang решили следующим образом: оператор * всегда означает произведение двух матриц, как принято в математике. Чтобы трансформировать вектор матрицей, нужно вместо m * v писать mul(v, m). Для такого старого ветерана OpenGL, как я, слегка непривычно, но жить можно 🙂

Репозиторий

Документация по языку

Обновления

Вышел bindbc-wgpu 0.22.0, соответствующий wgpu-native 22.1.0.1. Обновилось много чего по мелочи, из важного: теперь нужно удалять WGPURenderPassEncoder после отрисовки, иначе у вас wgpuQueueSubmit будет падать с ошибкой.

Соответственно, обновил и демонстрационное приложение wgpu-dlang, плюс избавился там от библиотеки STB для загрузки изображений.

Стеганография в dlib

Моя статья 2016 года, изначально написанная для блога LightHouse Software. Приведенный код актуален и сегодня.

Думаю, нет необходимости лишний раз говорить о том, насколько в наше время важна защита личных данных и тайна переписки. Конечно, к нашим услугам имеются криптографические алгоритмы, но одного только шифрования порой бывает мало – иногда нужно не просто передать секретное сообщение, но и скрыть сам факт передачи. И здесь приходят на помощь алгоритмы стеганографии.

(далее…)

Пример игры от третьего лица

Добавил в папку примеров Dagon демонстрацию управления от третьего лица. Персонаж работает на Newton-контроллере, поэтому будет реагировать со всеми телами, которые вы создадите через Newton. Можно вращать камеру вокруг персонажа, двигаться (WASD) и прыгать (пробел). Пример также показывает, как загружать модели формата IQM и воспроизводить анимацию.

Скачать

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

Интервью в «Вечерней Казани»

После упоминания на брюссельской конференции Dagon привлек внимание казанских журналистов: в «Вечерней Казани» сегодня вышло небольшое интервью, где я вкратце рассказал о проекте и о том, где и как он используется. По интересному совпадению, статью опубликовали в мой день рождения — получился своего рода подарок)

https://www.evening-kazan.ru/obshhestvo/articles/graficheskim-dvizhkom-kazanskogo-hudozhnika-polzuyutsya-geym-razrabotchiki-vsego-mira

Dagon на FOSDEM 2024

Классная новость: на прошедшей в феврале в Брюсселе FOSDEM ’24, европейской конференции по свободному программному обеспечению, американский профессор компьютерных наук Майк Шах (Mike Shah) представил доклад по языку D. В числе прочего, доклад включает информацию по Dagon. Отмечается, что это «существенный проект, который представляет интерес для графических разработчиков». Также упоминаются Dash, Hipreme Engine, BindBC и некоторые коммерческие игры, созданные с использованием D.

Ссылка на презентацию

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

Майк Шах — ученый в области компьютерной графики и визуализации, Ph.D. компьютерных наук, преподаватель Колледжа компьютерных наук Хури Северо-Восточного университета (Массачусетс).

Векторная графика в dlib

Моя статья 2017 года, изначально написанная для блога LightHouse Software. Приведенный код актуален и сегодня.

Коллекция библиотек dlib предоставляет функции для рисования отрезков и окружностей (см. dlib.image.render.shapes). Однако при построении сложной векторной графики не обойтись без рендеринга более интересных объектов – в этой статье я рассмотрел рисование закрашенных многоугольников и фигур Безье на их основе.

(далее…)

Dagon 0.17 и другие обновления

Выпустил новую версию движка Dagon. Релиз включает поддержку экранов с высокой частотой обновления, поддержку Wayland под Linux, новые методы класса Application для управления окном приложения и методы класса Game для управления сценами. Шейдер HUD-объектов теперь поддерживает прозрачность материала. Исправлен баг с неправильным удалением из памяти сцен GLTF, также исправлен прыжок в контроллере персонажей Newton. Движок и расширения теперь используют самые свежие версии всех BindBC-биндингов.

bindbc-soloud обновлен до версии 0.2 — биндинг теперь поддерживает SoLoud 20200207.

Обновлена демка механики игры Electronvolt: добавил главное меню, опции, паузу и множество других мелких улучшений.

Чем создавать res-файлы?

Если вы создаете софт под Windows, то наверняка сталкивались с файлами *.res — это бинарный формат ресурсов, который используется тулчейном от Microsoft. Такие файлы прилинковываются с программным кодом для встраивания в экзешник иконок, курсоров, а также информации о версии приложения и авторских правах. Утилита для компиляции ресурсных файлов (RC) входит в состав MSVS, но если вы по тем или иным причинам не хотите ее использовать, то вас ждет, мягко говоря, увлекательное приключение — какого-то стандартного общепринятого способа компилировать ресурсы нет.

Странно, что никто до сих пор не создал универсальный res-компилятор для любых языков — хотя свои компиляторы разной степени удобства включены во многие IDE и тулчейны. Например, в GNU Binutils есть для этого программа windres. Но чтобы ее использовать, вам, естественно, придется целиком установить виндовый порт GCC, например TDM-GCC или Winlibs, а это «могут не только лишь все», да и держать у себя такой громоздкий пакет ради одной утилиты как-то жирно. Я решил найти альтернативу, что-то простое и независимое — и вот вам на выбор два кандидата.

GoRC

http://www.godevtool.com/ResourceFrame.htm

К языку Go никакого отношения не имеет) Это freeware-компилятор res-файлов с синтаксисом, являющимся надмножеством RC от Microsoft. Поддерживает x64. Минимальный исходник для задания иконки приложения выглядит так:

100 ICON "app.ico"

Полученный файл можно включить в DUB-проект:

"sourceFiles-windows": ["resource.res"]

rcedit

https://github.com/electron/rcedit

Утилита от разработчиков Electron. Это не компилятор ресурсов — rcedit работает с экзешниками напрямую и позволяет добавить иконку или манифест уже собранному приложению. Очень удобно, если ваш язык не поддерживает линкинг ресурсов. Или, например, если вы используете какой-то готовый движок или рантайм, который не собираете самостоятельно (как, собственно, тот же Electron). Можно присобачить rcedit к DUB-проекту следующим образом:

"postBuildCommands-windows": [
    "$PACKAGE_DIR\\rcedit \"app.exe\" --set-file-version \"1.0.0.0\" --set-product-version \"1.0.0\" --set-icon \"$PACKAGE_DIR\\icon.ico\""
]