Проблема
Проблема - надо загружать в движок различные ресурсы: меши, текстуры, шейдеры. Если разнести эту работу по соответствующим классам, то каждый класс должен будет отвечать как за загрузку из файла данных, так и за правильную очистку используемой памяти. Это не очень удобно, так как в случае изменения, например, способа загрузки с диска придеться проверить и изменить все классы, которые грузят данные с диска. Плюс было бы удобнее вначале загрузить с диска в оперативную память все данные, и только после успешной загрузки отправить данные на GPU.
Решение - иметь один класс, который возвращает указатель на ресурсы, при необходимости подгружает данные с диска.
Менеджер ресурсов
Класс ResourceManager
загружает меши через библиотеку assimp
и хранит меши в unordered_map
, где ключ - название меша в файле. Перед тем, как получить объект типа Mesh
, необходимо загрузить меши из файла. Для этого необходимо вызвать метод ResourceManager::loadMeshesFromFile
.
Меш устанавливается для актора через MeshComponent::setMesh
. Чтобы получить объект типа Mesh
, необходимо вызвать метод getMesh
у объекта типа ResourceManager
.
Для размышления
В данной реализации есть некоторые недостатки и открытые вопросы:
- Что делать, если пользователь дал команду на удаление всех мешей из менеджера ресурсов, а актор, который использует данный меш, ещё существует? Стоит ли реализовать вместо сырых указателей интеллектуальные или вести подсчет количества использования мешей в
MeshComponent
и выдавать предупреждение, что меш удаляется раньше, чем прекращаеться его использование? - Сейчас обращение к менеджеру ресурсов идет через переменную в объекте типа
Game
. Однако менеджер ресурсов может быть только один. Не стоит ли определить его функции, с которыми работает пользователь (loadMeshFromFile
,getMesh
) статическими, чтобы не раскрывать реализации? - Загрузка данных реализована в виде метода класса
Game
. В библиотеке для real-time рендрингаfilament
от Google функции загрузки и выгрузки данных реализованы в виде вызываемых объектов, которые потом передаются в движок. Возможно, стоит это сделать и здесь.
Все эти вопросы требуют некоторой переботки кода и структуры, но в результате будет более удобная для пользователя реализация.
Заключение
Ссылка на GitHub