То, что вы описали здесь, называется Resource manager или, по крайней мере, частью менеджера ресурсов. Описание ресурсов во внешнем файле является хорошей практикой, поэтому вам нужен файл ресурсов, в котором все ваши сетки описаны в некотором роде (подумайте об использовании XML или JSON).
Иерархия классов
Вот возможный подход к иерархии классов:
Каждый VAO представляет собой сетку, определяя это координаты вершин, текстурные координаты, нормалей, цвета вершин и так далее. Я думаю, что нет оснований использовать тот же VBO в нескольких VAO, пока у вас не будет особого случая визуализации. Поэтому давайте предположим, что вы используете каждый набор данных только один раз, то есть классы, которые используют VAO, не должны знать ничего о базовых VBOs, и нет необходимости писать оболочку класса для VBO.
Набор сеток (может содержать только одну сетку) представляет собой модель. Минимальный класс модели должен включать дескриптор (ы) в VAO (ы) и информацию о преобразованиях геометрии (вращать, переводить, что угодно). Почему не строго одна сетка на модель? Иногда вам может потребоваться применить одно преобразование к группе сеток, из которых в свою очередь имеет свое собственное локальное преобразование модели.Например, такая композиция может использоваться для своего рода скелетной анимации или только для визуализации персонажа с произвольным оружием, взятым из библиотеки возможного оружия. Более того, вы можете объединить такие модели вместе, чтобы получить более сложные модели с одним и тем же интерфейсом, поэтому вы получите сходство scene graph. Во всяком случае, это хорошая идея использовать шаблон composite для класса модели.
Сцена должна включать коллекции моделей, источники света, поля силы и так далее.
менеджер ресурсов
Но откуда будет сцена (или подобный объект игры) получить его модели? Менеджер ресурсов должен ответить на этот вопрос. Сделайте каждую модель определенной определенным уникальным идентификатором. В простейшем случае путь в реальной или виртуальной файловой системе может рассматриваться как идентификатор, но он не очень гибкий. На мой взгляд, лучше определить все ячейки в файле ресурсов с помощью выразительных человекочитаемых имен и привязать каждое имя к набору данных (все типы коордов, цветов и т. Д.) И атрибутам. Весь ваш код не должен использовать модели напрямую, но он должен использовать ручки, предоставленные вам диспетчером ресурсов. Очевидно, что диспетчер ресурсов должен сохранять состояние во время выполнения программы и между вызовами из разных мест. Он предназначен для отслеживания, какие ячейки уже хранятся в памяти, и сохраняет идентификаторы VAO всех сохраненных сеток. Рассмотрите возможность использования шаблона singleton для менеджера ресурсов.
Пример:
ModelHandle footman = resMan->getModel("footman.model");
//.....
footman->setLocation(x,y,z);
footman->draw();
Здесь вызов getModel ("footman.model") начинается построение модели вызывает вызовы как
MeshHandle resMan->getMesh("footman1.mesh");
, чтобы получить все меши. И getMesh
делает это объяснение. Он проверяет, была ли такая сетка загружена раньше, и если да, она просто возвращает дескриптор в VAO, содержащий эту сетку. В противном случае он создает новый объект VAO, загружает в него запрашиваемые данные и возвращает дескриптор вновь созданному объекту. Все последующие запросы этого объекта не будут вызывать новое распределение VAO.
Несомненно, описанная организация графа сцены является приблизительным приближением к тому, как она должна выглядеть. Например, он не делает различия между модельным и абстрактным узлом графика сцены, но разработка и настройка этой иерархии для вашего двигателя зависит от вас.
Окончательный интерфейс к классу менеджера ресурсов - еще одна тема для обсуждения и проектирования. Некоторые вопросы и идеи:
- Вы будете использовать singleton или вы решите использовать глобальную переменную для некоторой причины ?
- Если вы решите использовать singleton, возможно, вы хотите иметь некоторые частные администраторы ресурсов, не являющихся одиночными, для ограниченного набора ресурсов ? Тогда рассмотрит проектирование синглтона в качестве шаблона обертывания класса, чтобы сделать возможным такой код:
ResourceHandle h1 = Singleton<ResourceMan>::instance->getResource("foo");
ResourceMan myPrivateManager;
ResourceHandle h2 = myPrivateManager.getResource("bar");
- будет управлять всеми видами ресурсов с одним всеобъемлющим менеджером или использовать специальный класс менеджера для каждого типа ресурсов? Второй подход лучше. Развивая идею второго подхода, зарядите свой компилятор, написав код для вас! Используйте класс диспетчера ресурсов шаблонов с небольшим подмножеством специализированного метода.Просто выделите один способ создания ресурса на тип ресурса и не получите все остальные коды управления ресурсами!
- Подумайте о ресурсе ресурса. Когда конкретный VAO должен быть уничтожен? Рассмотрите возможность использования эталонного счетчика и \ или заимствованной ссылки.
- Кэширование? Удалите данные из памяти хоста сразу после его загрузки на устройство (видеокарта) или сохраните его в течение некоторого времени? Как долго?
- Что относительно streaming? Он не должен быть доменом диспетчера ресурсов, но поддержка потоков может повлиять на него.
- glIsVertexArray функция и его аналоги могут быть полезны.
Сортировка
VAOs не единственный ресурс, который необходимо изменить при визуализации сцены. Вам также необходимо изменить текстуры, шейдеры и даже фреймбуферы. Обычный способ уменьшить количество изменений состояния - сортировать отображаемые объекты по некоторому свойству.
Например, очень вероятно, что вы будете отображать данную сетку только с одним шейдером. Вот почему сначала вы можете сортировать все сетки с помощью шейдера, поэтому вы минимизируете количество изменений шейдера. Затем для каждого шейдера (т. Е. В списке сеток для данного шейдера) вы можете сортировать сетки с помощью VAO, чтобы уменьшить количество изменений VAO до допустимого минимум. Сортировка по текстуре? Это зависит от вашего приложения, если вам нужно сортировать объект по текстуре и где это сделать.
Заключение
Подводя итог, если вы пишете движок игры, вам нужен менеджер ресурсов в любом случае. Если вы напишете быстрое и грязное частичное решение для VAO, то вы столкнетесь с теми же вопросами и проблемами с обработкой текстур, дополнительных фреймбуферов и многих других объектов, поэтому лучше реализовать хороший менеджер ресурсов один раз.
Полезные статьи, чтобы начать с:
http://www.gamedev.net/page/resources/_/technical/game-programming/a-resource-manager-for-game-assets-r3807
http://www.gamedev.net/page/resources/_/technical/game-programming/a-simple-fast-resource-manager-using-c-and-stl-r2503
Очень полезная книга:
http://www.gameenginebook.com/
похоже, что вы хотите [ARB_vertex_attrib_binding] (https://www.opengl.org/registry/specs/ARB/vertex_attrib_binding.txt) –
@ratchetfreak, поскольку я должен поддерживать OpenGL 3.3, nope. :( – Sorona