Биндинги это мостики между виртуальной машиной для исполнения и нативным кодом. Проблема в том, что эти биндинги приходится писать зачастую в ручную для каждого класса и для каждой функции. Если у вас много кода поддержка это безобразия превращается в сущий ад. Можно ли облегчить эту работу? Отчасти. Существенно, регистрацию байндингов облегчает так называемая "рефлексия". Рефлексией в программировании называется способность объекта рассказать о себе. Какие методы у него есть, какие свойства и другую важную информацию. К сожалению в C++ по умолчанию нет средств рефлексии классов. Разработчики вынуждены реализовывать ее самостоятельно. Но мы этого не боимся! Механизмы рефлексии есть во многих движках. Мета компилятор в UE, таблицы в Godot. Возможно что-то есть и в Unity. Но не факт! Используя рефлексию мы можем пройтись по всем известным нам классам и зарегистрировать их в системе скриптового движка. При изменении структуры класса, произойдет автоматическое обновление представление его в байндингах. К сожалению это работает только на классе поддерживающем рефлексию. Как правило унаследованном от базового класса типа "Object" для остальных классов и функций (математика, работа с файловой системой и пр.) по старинке приходится писать байндинги ручками. Но таких функций, благо, не много!
❤1🔥1🤯1
Как мы уже разобрали, рефлексия это полезно! Она помогает не только в работе со скриптовыми движками, но и с сериализацией объектов (способность объекта сохранять информацию о своем в буфер с дальнейшим сохранением на диск или отправкой по сети). Это очень существенный шаг от ООП к КОП (Компонентно Ориентированному Программированию). Общий принцип хранения информации о классе сводится к формированию специальных статических таблиц хранящих эту информацию. По необходимости эта информация извлекается и используется в ваших корыстных целях! Различия состоят лишь в том, каким образом формируются эти таблицы. По большому счету варианта 2. Либо программист заносит эту информацию в ручную и часто ошибается либо за него, ориентируясь по меткам, это делает Мета Компилятор. Мета компилятор это отдельная программа которая проходится по всем вашим исходникам и формирует эти таблички за вас. У обоих методов есть как плюсы, так и минусы:
Для ручного метода.
Плюсы:
- Не нужно писать утилиту отвечающую за парсинг и генерацию кода.
- Можно легко расширить и дополнить информацию.
Минусы:
- Необходимо описывать каждый класс вручную и поддерживать актуальность этих данных.
Для утилиты.
Плюсы:
- Автоматически обновляет все данные.
Минусы:
- Необходимо написать этот инструмент и встроить его в процесс построения игровых билдов.
- Расширение фичей может быть проблемным.
Для ручного метода.
Плюсы:
- Не нужно писать утилиту отвечающую за парсинг и генерацию кода.
- Можно легко расширить и дополнить информацию.
Минусы:
- Необходимо описывать каждый класс вручную и поддерживать актуальность этих данных.
Для утилиты.
Плюсы:
- Автоматически обновляет все данные.
Минусы:
- Необходимо написать этот инструмент и встроить его в процесс построения игровых билдов.
- Расширение фичей может быть проблемным.
Так как же обстоит дело с Thunder Engine? Хорошая новость в том, что в нем тоже есть рефлексия! Реализована она по первому принципу с небольшой модификацией предоставляющей небольшую защиту программиста от ошибок. Она основана на системе макросов и шаблонов. Позволяет разбирать методы и типы в полу автоматическом режиме. Подробней ознакомиться с ней можно здесь. А если вам интересно как оно устроено или вы желаете вынести себе мозг, добро пожаловать сюда, сюда, сюда и сюда. Но я вас предупреждал! Однако, платой за защиту от ошибок, является ухудшение возможностей расширения. Так, что этот метод, условно, можно назвать компромиссным. Но я не исключаю, что в будущем возьму курс на написание утилиты, отвечающей за интроспекцию и генерацию кода!
GitHub
thunder/thirdparty/next/inc/core/macros.h at master · thunder-engine/thunder
Thunder Engine – Cross-platform 2D and 3D game engine with modular architecture - thunder-engine/thunder
🔥2🥰1
Немного переделал систему управления стейт машиной рендеринга. Если вы не в курсе, помимо шейдера у пайплайна рендеринга есть и неуправляемые из шейдера части. Однако их можно дополнительно настраивать. Мне давно не нравилось как у меня сделана эта часть в OpenGL (кстати очень неудобная часть т.к. требует множество вызовов). В Vulkan все немного удобней. Эти изменения будут прокинуты в систему материалов и доступны для редактирования пользователями. Еще один шажок к большей гибкости!
🔥1🥰1🤯1
👻1
Усиленно готовлю доклад на эту тему. Очень хочется сделать его минимально нудным. Но ничего не обещаю =(
🔥4
До релиза остается неделя. И настало время подумать о том, что я бы хотел делать в следующем релизе. Напомню, что релизы у меня случаются каждые 3 месяца (если не происходит форс мажоров). Значит следующий релиз случится в конце Июня. Хотелось бы сделать многое, но руки у меня, к сожалению, всего 2 и необходимость еще работать на своей основной работе. Итак:
1. У меня есть изменения связанные с рефакторингом жизненного цикла ресурсов. Их бы я хотел закинуть как можно раньше, что-бы отловить возможные проблемы.
2. Продолжить начатый ранее рефакторинг материалов. Я поменял формат немного, приблизив его к представлению графических API. Теперь нужно дать возможность пользователям менять эти параметры.
3. Закончить импортер Spine 2D (возможно без бленд шейпов)
4. Хотелось бы переработать редактор эффектов (сейчас он сделан на QML частично). Хочу переделать на графы
5. Нужно продолжать совершенствовать редактор графов у себя. Добавить проброс редакторов и вертикальные порты.
6. Если останется времени поработать над системой анимации.
1. У меня есть изменения связанные с рефакторингом жизненного цикла ресурсов. Их бы я хотел закинуть как можно раньше, что-бы отловить возможные проблемы.
2. Продолжить начатый ранее рефакторинг материалов. Я поменял формат немного, приблизив его к представлению графических API. Теперь нужно дать возможность пользователям менять эти параметры.
3. Закончить импортер Spine 2D (возможно без бленд шейпов)
4. Хотелось бы переработать редактор эффектов (сейчас он сделан на QML частично). Хочу переделать на графы
5. Нужно продолжать совершенствовать редактор графов у себя. Добавить проброс редакторов и вертикальные порты.
6. Если останется времени поработать над системой анимации.
❤3👍2
Решил сегодня немного поработать над рендером с использованием вулкана. В целом началось все довольно безобидно. Я исправил работу Bloom фильтра. (он конечно далек от идеального). И тут остро встала проблема, которая зрела довольно давно. А именно ресурс текстур требует небольших изменений. Дело в том, что у меня довольно неочевидно создаются текстуры, используемые в качестве рендер таргетов. Мне давно не нравился текущий способ их объявления. Так что сегодня я заделал рефакторинг этого ресурса. В целом, его формат не поменялся. Я добавил дополнительную систему флагов, которые можно устанавливать для ресурса. На их основе система будет создавать (или не создавать) CPU части для текстур.
❤1🔥1🤯1
Итак о Render Targets. Если вы работали с шейдерами, вы возможно знаете, что выполняющийся шейдер не может делиться результатами со своим соседом. Проще говоря, вычисляя цвет пикселя, вы не можете подсмотреть в тетрадку соседа, что-бы списать. На самом деле это возможно в очень лимитированном виде. Но иногда, этот момент критически важен. К примеру, когда вы делаете размытие или еще что-то подобное. И тут на помощь приходят рендер таргеты. Грубо говоря, ваши результаты будут записаны в виртуальную текстуру, а на следующем шаге, уже другой шейдер, сможет их прочитать и использовать в своих вычислениях. Применительно к размытию, мы сперва делаем размытие по вертикали, сохраняем результат в текстуру, а потом получившийся результат размываем по горизонтали. На самом деле рендер таргеты очень активно используются в любом графическом пайплайне. Для отрисовки света и фильтров пост-обработки.
❤6
Продолжая разговор о Рендер Таргетах (RT), поговорим о Frame Buffers (FB) и их связи с ними. FB - это по сути сущность "контейнер" для RT. Перед вызовом отрисовки, разработчик может указать в какой FB необходимо нарисовать. К FB, заблаговременно, присоединяются различные таргеты. Color Attachments и опционально Depth Attachment. Вероятно вы заметили, что Color Attachments стоит во множественном числе. Все верно! К FB можно подключать больше одного буфера цвета (обычно до 8), эта фича называется Multiple Rendering Targets (MRT). Она очень активно используется для создания рендеров, с поддержкой множественных источников света. О разнице между Forward Rendering и Deferred Rendering мы поговорим немного позже. Для отрисовки одновременно в несколько цветовых текстур, разработчик должен указать несколько out переменных (для GLSL).
❤4👍1
Вот уже неделю я нахожусь в неравной схватке с рендером на Vulkan. Постепенно, задачи, которые казались неподдающимися, постепенно сдаются под напором. Прочитано много документации. Многие аспекты стали намного ясней. Некоторые подходы, были существенно переписаны. Вот и сегодня, поддалась проблема с Ортогональной матрицей проекции. В OpenGL было все просто. Построил матрицу и живешь себе, радуешься. Но как только попробовал использовать ту-же матрицу на Vulkan. Меня ждал неприятный сюрприз. Экран предательски оставался черным. Т.к. у меня несколько окон используют вулкан, я сперва грешил на проблему с синхронизаций очередей отрисовки. Убил 3 дня на это. Но проблема оказалось банальной и одновременно не очевидной. Все дело в Clip пространстве для Z координаты вершины. В OpenGL оно выглядит так. -w < z < w а в Vulkan 0 < z < w. Иначе говоря Vulkan не любит отрицательные координаты в по Z в gl_Position.
❤3👍2🔥1
Так как же починить ортогональную матрицу проекции, что бы не сломать все в OpenGL и поддержать вулкан? Нужно переместить пространство Z из -1...1 в 0...1. И вот вам немного кода.
Было:
Было:
Matrix4 Matrix4::ortho(areal left, areal right, areal bottom, areal top, areal znear, areal zfar) {
Matrix4 result;
result[0] = 2.0f / (right - left);
result[5] = 2.0f / (top - bottom);
result[10] = -2.0f / (zfar - znear);
result[12] = -((right + left) / (right - left));
result[13] = -((top + bottom) / (top - bottom));
result[14] = -((zfar + znear) / (zfar - znear));
return result;
}
❤2
Стало:
Matrix4 Matrix4::ortho(areal left, areal right, areal bottom, areal top, areal znear, areal zfar) {
Matrix4 result;
result[0] = 2.0f / (right - left);
result[5] = 2.0f / (top - bottom);
result[10] = 1.0f / (znear - zfar);
result[12] = -((right + left) / (right - left));
result[13] = -((top + bottom) / (top - bottom));
result[14] = znear / (zfar - znear);
return result;
}
Сегодня, как и было обещано, релизнул новую версию своего игрового движка! Было сделано много улучшений и еще больше исправлений! Благодаря обратной связи от Павла, добавил несколько полезных функций, о которых раньше не задумывался. Больше деталей можно прочитать в Release Notes:
https://github.com/thunder-engine/thunder/releases/tag/2024.2
https://github.com/thunder-engine/thunder/releases/tag/2024.2
GitHub
Release Release 2024.2 · thunder-engine/thunder
Features
Angel component shortcut (#706)
Editor: Add default lighting for prefab scene #700 (#701)
Editor: Basic UI editor #675 (#676)
Editor: Gizmo must support draw solid spheres #659 (#660)
Edi...
Angel component shortcut (#706)
Editor: Add default lighting for prefab scene #700 (#701)
Editor: Basic UI editor #675 (#676)
Editor: Gizmo must support draw solid spheres #659 (#660)
Edi...
🔥4❤1👍1
Итак, продолжим разговоры о графене. Как и обещал, поговорим Forward и Differed rendering. Изначально весь рендеринг был forward. Но что это значит? Это значит, что для рисуемого объекта сразу просчитываются эффекты и освещение. В ранних версия OpenGL (в до шейдерную эпоху) источники освещения задавались прямо из API. OpenGL поддерживал до 8 источников на экране. Но, что делать, если нужно больше? И нужны более гибкие настройки источников? Вот тут мудрые разработчики и придумали Deferred Shading (навел справки: 1988 год). Смысл подхода заключается, в дополнительном проходе формирующим Geometry Buffer (G-Buffer) в котором содержится вся необходимая информация. А свет просчитывает Отложено в экранном пространстве учитывая информацию из G-Buffer. Таким образом мы получаем поддержку огромного количества источников света. Возможность делать пост обработку на типа SSLR и SSAO. Однако, у этого метода есть один существенный минус. Если мы рисуем полу прозрачную поверхность. В G-Buffer не поместится (адекватно) информация о поверхности, находящейся под прозрачной. Так же не работает дефолтный антиалиясинг. Плюс, G-Buffer занимает дополнительную память (уже не так критично сейчас). Проблему полупрозрачных поверхностей решили третьим проходом. На первом проходе рисуются непрозрачные объекты. Потом накладывается свет. А потом, через Forward Pass, рисуются полупрозрачные объекты с ограниченным количеством источников света, влияющих на них.
🔥4❤1
В для каких случаев подходит Forard, а для каких Deferred? Все очень просто. Если у вас мало динамических источников света (2D игры или простенькие 3Д игры со стилизованной графикой и малым количеством источников). Оптимальней использовать Forward если вы хотите море света то Deferred ваш выбор. Есть еще более продвинутые техники. Может быть когда-нибудь поговорим и о них.
👍4❤1
Когда пишешь кроссплатформенный игровой движок. Всегда приходится смотреть на то, как поддерживается та, или иная фича графического API. Особенно это касается мобильных платформ. OpenGL ES очень аскетичен в этом плане. Вот так и сегодня. Только я хотел добавить поддержку Geometry Shaders. Как выяснилось, что они доступны только в ES 3.2. А это значит, что iOS платформа идет лесом. Так-же потенциально WebGL (когда-нибудь я до нее доберусь!). Похожая ситуация была и Shader Storage Buffer Objects на прошлой неделе. Похоже что, миграция на новые API становится все более актуальной =(
💔2🦄2🔥1
Простите. что давно ничего не писал. На данный момент я занят переработкой формата описания графов в редакторе. Хочу его сделать более читаемым для человеков. Так-же решил попробовать поучаствовать в Ludum Dare джеме с использованием своего движка. Надеюсь он не подкачает. Цель, сделать простенькую игру и выявить проблемные места.
❤6
Наконец доделал рефакторинг внутреннего формата описывающего графы в редакторе. Он стал гораздо компактней и читабельней. А, так-же есть задел на расширение функционала без изменения структуры формата. Я надеюсь, что не привнес слишком много новых багов. Задачка была не из простых.
👍4
Fixed:
Editor: "Local" property in particle editor is not saving #728
Editor: Add actor/component menu is not working in prefab #727
Editor: Areas on a Sprite are not saving #726
Editor: Infinite loading when import .wav file #725
Editor: "Local" property in particle editor is not saving #728
Editor: Add actor/component menu is not working in prefab #727
Editor: Areas on a Sprite are not saving #726
Editor: Infinite loading when import .wav file #725
❤2🔥1