SDL_Image и загрузчики текстур
Вслед за KTX я решил улучшить в движке ситуацию с поддержкой стандартных форматов изображений. Отныне Dagon загружает текстуры с помощью SDL_Image, если библиотека присутствует, системно или локально. В противном случае используется старый загрузчик на основе dlib.image
. Преимуществом такого подхода является гарантированная под Windows поддержка огромного числа форматов, включая современные WebP и AVIF; также автоматически решается застарелая проблема с декодированием прогрессивных JPEG.
А еще одно важное нововведение — механизм расширения этой системы. Теперь, если нужно добавить новый формат текстур, вместо кастомного ассета достаточно написать и зарегистрировать в AssetManager
‘е кастомный загрузчик текстур — реализацию абстрактного класса TextureLoader
. Он работает почти аналогично ассету, но предназначен для прямого декодирования данных в TextureBuffer
.
Этот подход — очередной большой шаг к отвязыванию Dagon от dlib.image
: объекты SuperImage
теперь используются только как промежуточный контейнер в случае недоступности SDL2_Image. На практике теперь в большинстве случаев SuperImage
вообще не создается — текстуры, как сжатые, так и несжатые, идут напрямую от загрузчика в OpenGL, а сами загрузчики полностью абстрактны.
Например, загрузчик KTX теперь является объектом KTXLoader
, который регистрируется как обработчик расширений «.ktx» и «.ktx2». Сам процесс загрузки KTX-текстур ничем не отличается от стандартного — добавляется лишь поддержка хинта TranscodeHint
:
TextureAsset aTextureBox;
TextureAsset aTextureEnvmap;
// В конструкторе сцены:
registerKTXLoader(assetManager);
// На стадии запроса ассетов:
aTextureBox = addTextureAsset("data/box.ktx2");
aTextureBox.conversion.hint = TranscodeHint.Size;
aTextureEnvmap = addTextureAsset("data/cubemap.ktx2");
aTextureEnvmap.conversion.hint = TranscodeHint.Quality;
В целом, система декодирования текстур оказалась самым сложносочиненным компонентом движка — и все из-за невероятного зоопарка форматов, которые необходимо поддерживать. Ушли те времена, когда достаточно было реализовать два-три простейших декодера для самых обыкновенных картинок RGBA32! Сегодня ситуацию отражают монструозные VkFormat и DXGI_FORMAT, на которые и смотреть-то страшно. Все текстуры поделились на две отдельные вселенные — с оффлайн-сжатием (PNG, JPEG и т.д.) и аппаратным сжатием (S3TC, BPTC…) — и, чтобы с одинаковым удобством работать и с теми, и с другими, движок обязан предусмотреть множество разных кейсов. А ведь есть еще внешние mip-уровни, кубические карты… Математически несложная задача — натянуть картинку на треугольники — превратилась в целую науку, отсюда и сложность.