2015-04-08 2 views
4

Насколько я понимаю: VAO представляет определенное состояние. Если я свяжу VAO, добавьте некоторые VBOs и буферы элементов для указаний и вещей, я могу сохранить определенное состояние объекта (ов), которое я хочу рисовать и активировать, и легко их рисовать позже по дороге, когда я хочу отображать материал. Правильно?Сколько VAO и VBO

Итак, VBO содержит фактические данные, а VAO - это только «оберточный объект», который содержит указатели на все буферы, которые я определил для него?

Изменение VAO является дорогостоящим (как меняется VBOs ?!). В настоящее время я загружаюсь в Meshes и объединяю их с моделями. Каждая модель использует свое собственное VAO и имеет VBO (с вершинами) и Element Buffer с их индексами.

Теперь, как я понимаю, это дерьмо, поскольку каждый объект в моем мире (который имеет модель) использует свое собственное ВАО. Не проблема для ~ 30 объектов в моем мире, но я хочу сделать это правильно, и в будущем могут быть сотни или тысячи объектов, а затем производительность резко снизится.

Итак, многие объекты «одинаковы» с точки зрения их моделей. Я имею в виду, если, например, у вас есть определенный тип дерева в мире, вы, вероятно, используете одну и ту же модель несколько раз, только в разных местах.

Теперь, как бы я это сделал? Должен ли я вручную отслеживать мои VAOs как: (псевдо-код, следующий!)

treesVAOId = 1; 
rabbitsVAOId = 2; 

, а затем, если я загружаю модель просто проверить, если ID был уже связан (как?) И добавить еще один набор РВО там (или даже добавить в правый VBO? если да, то как?)

Я думаю о большой игре здесь. Предположим, что в игре тысячи персонажей. Конечно, не все они отображаются одновременно, но я не могу создать VAO и VBO для каждого из них, не так ли?

Я чувствую, что пропала большая часть ... как бы внедряя и используя (более или менее) те же данные снова для разных целей эффективно.

Это один шаг, который мне не хватает, как реально оптимизировать использование VAO и VBOs в реальном мире.

+0

похоже, что вы хотите [ARB_vertex_attrib_binding] (https://www.opengl.org/registry/specs/ARB/vertex_attrib_binding.txt) –

+0

@ratchetfreak, поскольку я должен поддерживать OpenGL 3.3, nope. :( – Sorona

ответ

8

То, что вы описали здесь, называется 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/

+0

Спасибо. Ну, на самом деле ваш ответ немного не по теме, потому что я до сих пор не уверен, сколько VAO и VBOs в порядке. Если у каждой модели есть своя собственная VAO, я был именно сейчас. (У меня уже есть модель и класс Mesh. Просто каждый объект Entity в моем проекте имеет одну модель, следовательно, это собственный VAO). Проблема, с которой я сталкиваюсь, заключается в том, что я хочу, чтобы моя игра хорошо работала с сотнями объектов, а не просто десятки, и мне интересно, не слишком ли ресурс, как переключение VAO и VBOs. – Sorona

+0

@Teolha Я думаю, что невозможно дать точное число VAO, которое будет хорошо работать, потому что это зависит от многих вещей: чип-модель, ОС и драйвер, тип хост-машины. Единственное, что вы можете сделать, это уменьшить количество изменений состояния и нарисовать вызовы. Я добавил раздел о сортировке, но также может потребоваться удаление отрывков, окклюзионные запросы или какой-либо тип разбиения пространства. Обработанные процессором методы отбора могут (но не обязательно) в потому что они могут исключать некоторые виды сеток из обработки и, следовательно, уменьшать не только количество изменений состояния, но также и количество вершинных шейдеров. – Sergey

+0

Конечно, вы правы, и я не предполагал, что существует глобальный ответ на «сколько vaos/vbos в порядке», а скорее на том, как структурировать приложение для повторного использования vaos/vbos для одних и тех же моделей в эффективный способ, а также возможность устанавливать их на разных позициях и манипулировать только одной моделью, а не всего. Вроде того. Если я попаду в Tree-Model, я хочу это, и только эта древовидная модель ответит на это, а не на все, хотя они ссылаются на один и тот же vao/vbo. – Sorona

2

изменяющемся VAOs не , что дорого. Точные цифры, очевидно, сильно зависят от оборудования и платформы. Но только для того, чтобы дать вам приблизительную идею, я несколько раз менял номера для переключателей VAO/секунду на низких миллионах ноутбуков. Гипотетически предположим, что ваша машина может переключать VAO 6 миллионов раз/секунду. Если вы хотите достичь 60 кадров в секунду с такой скоростью, вы можете переключить VAO на 100 000 раз за кадр.

Теперь, конечно, вы не хотите использовать все время процессора для переключения VAO. У вашего приложения будет много другого состояния для изменения, вам придется обрабатывать собственную логику приложения, и в идеале вы не хотите, чтобы ваша общая загрузка процессора была как можно ниже. Поэтому я не хотел бы приближаться к числу выше. Тем не менее, переключение VAO 1000 раз за кадр не должно быть проблемой на достаточно высокопроизводительном компьютере/устройстве.

Это действительно сопоставимо с другими изменениями состояния, которые вы обычно делаете между обратными вызовами. Вы всегда хотите свести их к минимуму (а также количество самих призывов к розыгрышу).Но что касается изменений состояния, то привязка другого ВАО обычно является относительно дешевым.

Если у вас есть объекты, которые имеют одну и ту же геометрию, например деревья в вашем примере, вы, разумеется, не должны иметь несколько копий одних и тех же данных. Это просто здравый смысл и даже не имеет особого отношения к графике. Отмахивание памяти, конечно, нежелательно. И даже если вы не в отчаянном кризисе памяти, наличие нескольких копий одних и тех же данных может повредить производительность, потому что это, скорее всего, снизит ваши ставки попадания в кеш.

Как создать свою игру, чтобы сделать эту работу лучше всего, это довольно широкий вопрос для этого формата. Ну, и я никогда не писал серьезной игры, так что я не идеально квалифицирован, чтобы дать вам совет в любом случае. Моим первым инстинктом было бы иметь группу классов, которые определяют разные формы. Например, у вас может быть TreeShape, которому принадлежит геометрия (VAO и VBO) для дерева. То же самое для каждого вид характера. Затем, если ваша сцена содержит кучу деревьев, у вас есть класс Tree, который описывает конкретные деревья, где экземпляры могут содержать только информацию о позиции/размере дерева, но все они имеют ссылку на тот же TreeShape. Таким образом, все деревья имеют один и тот же VAO/VBO, используя тот же TreeShape, и каждый конкретный Tree содержит только информацию, которая фактически различна для каждого экземпляра дерева.

Смежные вопросы