Проектирование (текстуры) системы ресурсов

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

Начальная точка была (в основном) Loader учебный класс заголовок/Src

Формат ресурсов:

  • Ресурсы (как правило) находятся в архивах, которые состоят из пронумерованных файлов (без имен), которые могут быть любого типа и могут содержать связанные метаданные (размер, смещение отрисовки, …)
  • Часто распространенные форматы (wav, midi, bmp), но возможны пользовательские форматы, например, для текстур:
    • 2D Offset (перевод матрицы модели)
    • Цветная маска игрока (дополнительная шкала серого bmp)
    • Разделенные BMP (например, ссылки (индексы) на тело и голову (BMP) для повторного использования BMP в том же файле)
  • Возможны расширения / перезаписи: 2 архива с одинаковыми именами (разные папки) объединят их (позже загруженные записи архива добавляют или перезаписывают записи предыдущих)

Проблемы, которые я хотел решить, это грязный код (без SRP …), неравномерная обработка ресурсов и dynamic_cast для большинства обращений (в основном: dynamic_cast<type*>(Get("foo", 42))). Наличие только одного типа текстуры также упростит рендеринг (возможно, 2: один с масками игрока, а другой без)

Мой подход (основанный на ENTT):

  • ResourceLocator: С учетом имени возвращает список архивов для загрузки (обрабатывает расширение / перезапись)
  • ResourceCache<Type>: Содержит загруженный ресурс данного типа
  • ResourceLoader<Type>: Загружает ресурс
  • ResourceRegistry: Содержит несколько кэшей, 1 локатор и (возможно) загрузчики. Предоставляет доступ ко всем ресурсам, сначала проверив кеш и загрузив его по ошибке (добавив в кеш)

Это хорошо работает для звуковых эффектов и музыки:

SoundEffect& get(ResId id){
if(id in soundcache) return it;
archive& = get(id.name);
SoundEffect* effect = load(archive)
add to cache and return effect;
}

Это мило и универсально. Но я борюсь за то, как это сделать для текстур, для которых у меня есть разные типы:

  • «нормальные» текстуры (фоны, кнопки …) -> легко
  • специфичные для карты текстуры (например, деревья со снегом или без снега в зависимости от типа карты. Ранее Loader хранится ссылка на архив карты, а потребители просто называют GetMapTexture(idx) -> может не потребоваться для всех карт, я должен выгрузить их все при смене карты и перезагрузить по мере необходимости?
  • национальные текстуры (каждая нация имеет архив и / или смещение в архиве) -> Использование ("archive", number) так как ключ больше не работает.

Кроме того, может потребоваться объединение множества текстур (например, разделенных растровых изображений или теней со зданиями / людьми …) и анимация. Это привело к мульти-D-массивы фиксированного размера со многими различными индексами, где значение содержится в Loader учебный класс.

Таким образом, «нормальные» текстуры просты: просто загрузите их в текстуру OGL и используйте их. Другим нужно (обычно) несколько изображений, объединенных в одну текстуру. Поэтому я не хочу помещать эти части в кеш текстуры, а только в комбинированный. Но наличие этих мульти-D-массивов также кажется недостатком дизайна. И как я буду ссылаться на них / использовать их? Как другие это делают?

Примечание. Индексы изображений, составляющих текстуру / bld …, можно (вроде) легко вычислить из индекса нации, индекса построения, индекса кадра анимации, …

Пример использования (из текущего / старого) кода:

drawAnimal(int type, int dir, int animationFrame){animal_cache[type][dir][animationFrame].draw(pos...);}
drawCarrier(...){carrier_cache[carriedWare][dir][animationFrame][isFat].draw(pos, playerColor,...);}
drawBuilding(...){building_cache[nationIdx][bldIdx].draw(pos, playerColor,...);}

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]