martianov_dev
53 subscribers
17 photos
10 videos
5 links
Привет! Добро пожаловать в мой devlog. Я увлечен изучением технических аспектов разработки компьютерных игр и с радостью делюсь своими открытиями и проектами с вами! @martianov
Download Telegram
Года два назад на новой работе отдал свой код на ревью и получил неожиданную реакцию.

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

Пока многие спорят о табуляциях и пробелах, существует еще одно разделение - между стилями K&R и Allman. Я-то всю жизнь писал в стиле K&R, даже не задумываясь об этом. Этот стиль я впитал из книг по C и C++, которые читал в юности.
K&R стиль, названный в честь создателей языка C, экономит место на экране и делает код компактнее. Это было особенно важно раньше, когда разрешение мониторов было низким. А стиль Allman, где скобка ставится на новой строке, больше распространен например в JavaScript.

Забавно, что я только сейчас осознал, насколько глубоко во мне укоренился K&R стиль. Это как открыть в себе неожиданную черту характера. Кто бы мог подумать 🙃
7🔥4👍3
Написал редактор для амбициозного сайд-проекта!

Поставил себе цель - написать редактор кода для одной непростой программы. Но вот незадача: проект написан на чистом C99, без готовых UI-библиотек, и уж тем более без готовых а-ля "компонентов" текстового редактора.

Из абстракций над графикой у меня только "холст" и базовые команды: отрисовка текста / прямоугольников и прочие вспомогательные функции для работы со шрифтом. Но и этого достаточно - остальное дело скилла! Помню, писал что-то подобное для игры на Defold Engine, но там было проще: Lua и готовые решения. А тут голый C!

Первая сложность: работа с массивами байтов вместо удобных строк, как в C++ или Lua. Пришлось либо кодить вручную, либо писать свои абстракции. Начал с простого API для работы со строками на более высоком уровне (скриншот приложил). В процессе прослезился, вспомнив все процедурные языки, на которых кодил в школе... Никакого ООП! Но оказалось, что и без него жить можно - даже классно.

Дальше - дело техники: разбивка текста на строки, расчёт ширины символов, обработка позиции курсора относительно мыши, выделение текста, ввод, конкатенация и сохранение на диск. И всё это — на низком уровне, с минимумом доступных функций.

Зачем такие сложности? Этот проект - максимально легковесный и портируемый начиная с веб, заканчивая Raspberry Pi, FreeBSD, и даже PSP (хотя в последнем случае это просто фан, но возможность все же есть). А редактор кода внезапно стал необходим.

Получилось, на мой взгляд, отлично: никаких утечек памяти, хотя я мысленно молюсь на алгоритмы дефрагментации ОЗУ в той системе, где запустится программа. 😂

Кстати, особенно доволен что сразу внедрил поддержку utf8, правда пришлось в каком то моменте некоторые алгоритмы пересмотреть.

Спасибо!
🔥62👍2👻1😨1
Ну что, давненько я не писал про шейдеры! Пришёл к вам с реймачингом и довольно нестандартной задачей.

Наконец-то зацепил одну из своих давних целей - восстановить 3D-форму, используя только карты высот с шести ракурсов. Писать конвертер в меш скучно, а вот запилить шейдер, который в реальном времени рендерит объект через реймачинг вот это уже веселье!

В чём прикол?
Вместо классического рендеринга полигонов (треугольники и всё такое) я использовал пошаговый алгоритм, который проверяет пересечение лучей с виртуальной сценой. Сцена может быть задана либо математическими функциями (SDF — Signed Distance Functions), либо, как в моём случае, картами высот.

Я взял Blender, поставил Сюзанну в центр и сгенерил 6 карт высот (фронт, бэк, лево, право, верх, низ). Шейдер берёт каждую карту и строит по ней выпуклый объект (как если бы мы "выдавливали" форму из карты высот). Затем все эти формы перемножаются (логическое И), оставляя только их общее пересечение. И вуаля! Мы получаем что-то, что напоминает исходную 3D-модель!

Почему это огонь?
Потому что это альтернативный подход к 3D-реконструкции, который работает полностью в реальном времени и без явного хранения меша. Всё считается на лету в шейдере, и можно легко играться с параметрами, добавлять шум, менять детализацию, и всё это без пересчёта геометрии. + Как бонус очень легко сделать SSAO, и прочие эффекты освещения.

Переводил цвет в 8-bit для того, чтобы я смог сохранить информацию об геометрии и цвете в одной 1024x1024 текстуре. Одна текстура = одна модель. Хотя хоть на диске эта "модель" в моем формате занимает всего 200кб(!), но на видеокарте распакуется во все 3мб.

Конечно, это не идеально точный метод из-за ограничений выбранных проекций, но как эксперимент просто офигенно
🔥7👍2😨21👻1
Пиши шейдер один раз - запускай везде

Начну с того, что если пишешь под десктоп, то шейдеры можно писать на классическом GLSL (версии 120, 130, 330, 430 и т. д.) или на HLSL, если работаете с DirectX. А вот для веба и мобилок обычно используют GLSL ES (упрощённая версия под OpenGL ES) - например, 100 (ES 2.0), 300 (ES 3.0) и т. д. Разница между ними не огромная, но есть нюансы: В новых версиях появляются layout qualifiers, другие типы данных, чуть иной синтаксис. В GLSL ES, например, нельзя просто так взять и объявить переменную без "precision" в фрагментном шейдере и прочие нюансы.

Но иногда хочется писать на современном GLSL 450+, а потом оказывается что на телефоне или в браузере это не запустится. И приходится переписывать кучу кода под каждую платформу.

И тут начинается для большинства абсолютная магия!

В игровых движках типа Unity, Unreal, Godot и даже game maker, всё это уже решено - шейдеры автоматически адаптируются под разные платформы. Например, в Defold недавно завезли поддержку SPIRV-Cross. Говоря отдельно про саму либу, то она умеет превращать шейдеры из SPIR-V (промежуточный бинарный формат) в:
- GLSL (любой версии),
- GLSL ES (для мобилок и веба),
- HLSL (под DirectX),
- MSL (под Metal, для Apple).

SPIR-V это как универсальный байткод для шейдеров. Его можно получить, например, из GLSL с помощью glslang (официальный компилятор от Khronos) или даже из HLSL c помощью DirectXShaderCompiler (не я не проверял)

Я залип на эту тему

Помучился, почитал доки, даже брал консультацию у спецов, чтобы помогли собрать ради спорт интереса glslang + SPIRV-Cross в один бинарник настроив нужные команды лично под меня. Теперь я могу:
1. Написать шейдер на современном GLSL.
2. Скомпилить его в SPIR-V.
3. Конвертнуть в любую целевую версию - хоть под WebGL, хоть под Vulkan или DirectX.

Вот ссылки на проекты благодаря чему это возможно, там же есть собранные отдельные бинарники для быстрых тестов:
SPIRV-Cross https://github.com/KhronosGroup/SPIRV-Cross
glslang https://github.com/KhronosGroup/glslang
5🔥4👍3