Обновления OpenGL VBO

Мне нужно нарисовать буфер, содержащий несколько тысяч вершин. Я использую vbo для хранения данных.

Я знаю, что мне придется обновлять VBO много раз - но только по небольшим частям за раз.

Итак, мне интересно, что лучший способ сделать это:

  • Разделить VBO на более мелкие VBO (которые держатся как 300 вершин), а затем обновить отдельные VBO с помощью 1 вызова?
  • Один большой VBO и используйте лоты вызовов glBufferSubData()?
  • Используйте glMapBuffer() и один большой VBO?

Ответы

Ответ 1

Существует еще один вариант, который немного похож на вариант 3 - используйте один большой VBO (возможно, с режимом GL_STREAM_DRAW), который reset каждый кадр (путем вызова glBufferData с указателем буфера NULL и одинаковый размер каждый раз), затем glMapBuffer -ed сразу. Буфер отображается на карту, поскольку он заполняется, а затем не отображается непосредственно перед рисованием. Повторить.

Вызов glBufferData сообщает OpenGL, что старое содержимое буфера не требуется, поэтому glMapBuffer не может потенциально ждать, чтобы GPU завершил работу с графическим процессором.

Этот подход, похоже, официально санкционирован расширением vertex_buffer_object. См. "Вершинные массивы с использованием отображаемого объекта буфера":

http://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt

Это говорит о том, что OpenGL (или драйвер?) будет следить за подобным поведением и (когда замечено) упорядочивает вещи так, чтобы они выполнялись эффективно.

Ответ 2

  • Звучит не очень хорошая идея: он заставляет вас рисовать его в нескольких вызовах, изменяя связанный буфер между каждым вызовом розыгрыша.
  • Можете сделать трюк, если ваш буфер огромен.
  • Весь буфер, безусловно, будет загружен на GPU. Это, безусловно, будет столь же эффективным, как один glBufferData, но вы можете сделать это асинхронно.

Если вы считаете, что glBufferData или glMapBuffer являются лучшим решением, если ваш буфер невелик. 100000 * sizeof(float) * 3 ~= 1MB. Там не должно быть никаких проблем.