Как использовать OpenGL 3.X VBOs для визуализации динамического мира?
хотя, похоже, очень мало современных ссылок на OpenGL 3.x сам по себе, фактическая низкоуровневая манипуляция OpenGL относительно прямолинейна. Однако у меня серьезные проблемы с попыткой даже концептуализировать, как можно манипулировать VBOs, чтобы сделать динамический мир.
очевидно, что способы немедленного режима старых неприменимы, но оттуда, куда я иду? Я пишу какую-то структуру сцены, а затем преобразовать их в набор вершин и передайте это на VBO, как я буду хранить данные перевода? Если да,то как это будет выглядеть?
в основном действительно не уверен, как продолжить.
3 ответов
Если весь ваш мир действительно динамичен, вы можете использовать GL_STREAM_DRAW_ARB
флаг использования и сброс данных на каждом кадре. Не утруждайте себя манипулированием, просто старайтесь передавать как можно эффективнее.
однако я предполагаю, что у вас есть сцена, состоящая из нескольких жестких объектов, которые перемещаются относительно друг друга. В этом случае используйте по одному VBO для каждого объекта и укажите GL_STATIC_DRAW_ARB
флаг использования. Затем вы можете установить преобразование modelview для каждого экземпляра объекта и отобразить их с помощью один вызов draw на экземпляр.
эмпирическое правило (на ПК) должно выдавать не более одного вызова draw на Мгц вашего процессора. Это грубая оценка, но в ней есть доля правды. Не беспокойтесь о размещении нескольких независимых объектов в одном VBO или других трюках производительности, если вы остаетесь ниже этого предела.
короткий ответ:
использовать glMapBufferRange и только обновить поддиапазон, который нуждается в модификации.
ответ:
фокус в том, чтобы сопоставить уже существующий буфер с glMapBufferRange, а затем только карту диапазон вам нужно. Учитывая эти предположения:
- ваша геометрия использует для каждой вершины анимацию морфинга
- число вершин для моделей является постоянным во время анимации.
затем вы можете использовать glMapBufferRange обновить только изменяющиеся части и оставить остальные данные в покое. Полные загрузки с помощью glBufferData медленны, как черепаха, потому что они удаляют старое хранилище памяти и выделяют новое. Это в дополнение к загрузке новых данных. glMapBufferRange только позволяет читать / записывать существующие данные, он не делает выделения или освобождения.
однако, если вы используете анимация скелета, а не передавать преобразования вершин в виде матриц 4x4 на вершину в шейдер вершин и выполнять вычисления там. Данные для каждой вершины, конечно, указываются с помощью glVertexAttribPointer.
кроме того, помните, что вы можете читать данные текстуры в шейдере вершин и что OpenGL 3.1 ввел некоторые новые вызовы рисования экземпляров; glDrawArraysInstanced и glDrawElementsInstanced. Те совмещенные можно использовать например-специфический поиски. Т. е. вы можете выполнять вызовы экземпляра с теми же данными геометрии, но отправлять позиции или любые данные на вершину, которые вам нужны как текстуры или массивы текстур. Это может избавить вас от смешивания и сопоставления различных наборов данных массива вершин.
представьте, что вы хотите отобразить 100 экземпляров одной и той же модели, но с разными позициями или цветовыми схемами. Или даже текстурные карты.
использование VBOs не означает, что вы должны отображать всю сцену только с одним вызовом draw. Вы все еще можете выполнить несколько вызовов рисования и настроить различные матрицы преобразования по пути.
например, если вы используете scenegraph, каждая модель в scenegraph может соответствовать одному вызову draw. В таком случае самый простой способ использования VBOs-это создание отдельного VBO для каждой модели.
в качестве оптимизации вы можете объединить несколько моделей в один VBO, а затем передать ненулевые смещения при выполнении вызовов draw; это вырывает правильную модель из VBO. Также желательно объединить несколько вызовов draw в один вызов draw, но это невозможно, если им нужны независимые преобразования. (На самом деле это is возможно в определенных ситуациях, если вы используете instancing или vertex blending,но я предлагаю сначала получить основы.)