Как я могу использовать OpenGL 3.x VBO для рендеринга динамического мира? - PullRequest
9 голосов
/ 13 ноября 2009

Хотя, кажется, очень мало актуальных ссылок для самого OpenGL 3.x, фактические низкоуровневые манипуляции с OpenGL относительно просты. Однако я испытываю серьезные затруднения, пытаясь даже придумать, как можно манипулировать VBO для создания динамического мира.

Очевидно, что старые способы непосредственного использования неприменимы, но откуда мне идти? Пишу ли я какую-то структуру сцены, а затем преобразовываю ее в набор вершин и передаю ее в VBO, как мне хранить данные перевода? Если так, то как бы это выглядело разумно?

По сути, действительно не знаете, как продолжить.

Ответы [ 3 ]

9 голосов
/ 13 ноября 2009

Если весь ваш мир действительно динамичен, вы можете использовать флаг использования GL_STREAM_DRAW_ARB и сбросить данные в каждом кадре. Не пытайтесь манипулировать им, просто попытайтесь транслировать как можно эффективнее.

Однако я предполагаю, что у вас есть сцена, состоящая из нескольких жестких объектов, которые движутся относительно друг друга. В этом случае используйте один VBO для каждого объекта и укажите флаг использования GL_STATIC_DRAW_ARB. Затем вы можете установить преобразование вида модели для каждого экземпляра объекта и отобразить их, используя один вызов отрисовки на экземпляр.

Основное правило (на ПК) - выполнять не более одного вызова отрисовки на МГц вашего ЦП. Это грубая оценка, но в этом есть доля правды. Не беспокойтесь о размещении нескольких независимых объектов в одном VBO или других приемах повышения производительности, если вы остаетесь ниже этого предела.

9 голосов
/ 14 ноября 2009

Краткий ответ:

Используйте glMapBufferRange и обновляйте только поддиапазон, который требует модификации.

Длинный ответ:

Хитрость заключается в том, чтобы сопоставить уже существующий буфер с glMapBufferRange , а затем отображать только необходимый диапазон. Учитывая эти предположения:

  • Ваша геометрия использует морфинг анимации для каждой вершины
  • Число вершин для моделей постоянно во время анимации.

Затем вы можете использовать glMapBufferRange , чтобы обновить только изменяющиеся части и оставить оставшиеся данные в покое. Полные загрузки с использованием glBufferData медленны как черепаха, потому что они удаляют старое хранилище памяти и выделяют новое. Это в дополнение к загрузке новых данных. glMapBufferRange позволяет только читать / записывать существующие данные, не выделяет и не освобождает.

Однако, если вы используете скелетную анимацию, передайте вершинные преобразования как матрицы 4x4 на каждую вершину вершинному шейдеру и выполните вычисления там. Данные для каждой вершины, конечно, указываются с помощью glVertexAttribPointer .

Также помните, что вы можете читать данные текстуры в вершинном шейдере, и что OpenGL 3.1 ввел несколько новых вызовов отрисовки экземпляра; glDrawArraysInstanced и glDrawElementsInstanced . Их можно использовать для поиска конкретных экземпляров. Т.е. вы можете выполнять вызовы отрисовки экземпляра с той же привязкой данных геометрии, но отправлять позиции или любые данные по каждой вершине, которые вам нужны, в качестве текстур или массивов текстур. Это может уберечь вас от смешивания и сопоставления различных наборов данных массива вершин.

Представьте, хотите ли вы визуализировать 100 экземпляров одной и той же модели, но с разными позициями или цветовыми схемами. Или даже карты текстур.

5 голосов
/ 13 ноября 2009

Использование VBO не означает, что вы должны визуализировать всю сцену с помощью всего одного вызова. Вы по-прежнему можете выполнять несколько вызовов отрисовки и устанавливать различные матрицы преобразования по пути.

Например, если вы используете сценограф, каждая модель в графе сцены может соответствовать одному вызову отрисовки. В таком случае самый простой способ использования VBO - это создание отдельного VBO для каждой модели.

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

...