2009-11-13 1 views
9

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

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

В принципе действительно неуверенный, как продолжить.

ответ

9

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

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

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

+1

+1 для распознавания пакетной обработки как самой большой проблемы с графическим кодированием в эти дни. 1 draw call per Mhz кажется оптимистичным для меня после некоторого кодирования OpenGL ES iPhone - я нашел, что я ограничен 30-40 партиями, чтобы поддерживать приличную частоту кадров! – tsalter

+0

Хорошо, я должен был добавить, что это правило может не применяться непосредственно к мобильным устройствам. Несколько лет назад я видел это на некоторых слайдах GDC, и он отлично меня обслуживал на ПК с ОС Windows. –

+0

Btw, я только что нашел слайды здесь: http://ati.amd.com/developer/gdc/D3DTutorial3_Pipeline_Performance.pdf (в основном D3D9, OpenGL на странице 28) –

5

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

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

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

9

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

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

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

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

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

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

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

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

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

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