Я вижу, что OpenGL версии 3 и выше исключают использование рендеринга на стороне клиента. Немедленный режим был исключен, и массивы вершин, похоже, устарели. Вместо этого, если я правильно понимаю, VBO являются основным способом рендеринга вершин.
Хотя я вижу логику в том, чтобы иметь единый способ рендеринга всего, разве в том случае, если у VBO нет больших недостатков по сравнению с массивами вершин? Я думал, что VBO должны быть большими буферами, содержащими> 1 МБ данных, как правило. Что если у меня есть сцена, которая имеет меньшую геометрию? У меня есть граф сцены с большим количеством узлов, каждый из которых нуждается в своем собственном преобразовании и т. Д. Каждый узел также должен иметь возможность удалять отдельно, добавляться отдельно и т. Д. Я использовал массивы вершин раньше. Итак, мой первый вопрос заключается в том, будет ли, если я переключусь на VBO, увеличивать издержки на мои объекты графа сцены сейчас, потому что VBO необходимо выделить для каждого объекта.
Другая проблема заключается в том, что рендеринг геометрии может быть очень динамичным. В худшем случае могут быть моменты, когда всю геометрию необходимо повторно отправлять каждый кадр в течение некоторого периода времени. В этом случае производительность VBO будет хуже, чем у вершинных массивов, или в худшем случае VBO будет выполнять столько же работы, сколько и у вершинных массивов, но не больше?
Итак, в более кратком формате, мои вопросы:
1) Существуют ли существенные накладные расходы на распределение / освобождение VBO (я имею в виду простой акт настройки буфера)?
2) Если я обновляю данные из CPU каждый кадр, может ли это быть значительно хуже, чем если бы я использовал массивы вершин?
И, наконец, я хотел бы знать:
3) Если ответ на любой из приведенных выше вопросов «да», зачем отказываться от других режимов рендеринга, которые могут иметь преимущества перед VBO? Есть ли что-то, чего я здесь упускаю, например, методы, которые я должен использовать, чтобы смягчить некоторые из этих потенциальных затрат на распределение и т. Д.?
4) Существенно ли меняются ответы на эти вопросы в зависимости от того, какую версию OpenGL я использую? Если я сделаю рефакторинг своего кода, чтобы он был совместим с OpenGL 3 или 4, используя VBO таким образом, чтобы он был эффективным, будут ли те же самые методы работать хорошо с OpenGL 2, или вероятно, что некоторые методы будут намного быстрее с OpenGL 3 + и другие с OpenGL 2?
Я задал этот вопрос о переполнении стека, но я пересылаю сюда, потому что я понял, что этот сайт может быть более подходящим для моего вопроса.
источник
Ответы:
Определите «существенный». Как правило, не рекомендуется создавать их в середине кадра; они должны быть установлены во время инициализации или где угодно. Но это верно для большинства объектов OpenGL, таких как текстуры, рендер-буферы или шейдеры.
Может это? Да. OpenGL определяет функциональность, а не производительность . Вы действительно можете сделать вещи намного медленнее. Или вы можете сделать вещи быстрее. Все зависит от того, как вы его используете.
В OpenGL Wiki есть хорошая статья о том, как правильно передавать данные .
Во-первых, они не просто устарели. Устаревание означает пометку чего-либо как «подлежащего удалению» в будущих версиях. Они устарели в версии 3.0 и удалены в ядре версии 3.1 и выше.
Во-вторых, ARB обычно объясняет причину, по которой они удалили материал из OpenGL. Это делает спецификацию меньше и проще. Это делает API меньше и более упорядоченным. Это помогает узнать, какие API вы должны использовать; 2.1 было 4 способа предоставления данных вершин; 3.1+ имеет 1. Это избавляет от большого количества беспорядка. И т.п.
Более или менее нет. Только на MacOSX разница между версиями 3.1 + core и pre-3.0 действительно очевидна. Профиль совместимости реализован всеми драйверами для Linux и Windows, поэтому вы можете предположить, что профиль ядра из этих драйверов на самом деле просто добавляет проверки, чтобы не вызывать функции совместимости.
Под Mac OSX 10.7 доступно ядро GL 3.2, но нет профиля совместимости. Это не обязательно что-то значит для техник исполнения одного против другого. Но это означает, что если есть различия, то на этой платформе вы их увидите.
источник
Как работает OpenGL, всякий раз, когда вы используете данные, не относящиеся к VBO, драйвер должен сделать их копию - на практике создавая временный VBO - поскольку ничто не мешает вам изменять ваши голые массивы пользовательского пространства между вызовами OpenGL.
Может быть некоторая хитрость на стороне водителя, чтобы ускорить выделение времени, но вы ничего не можете сделать, чтобы избежать копирования.
Так что да, пока вы - и разработчики драйверов - все делаете правильно, VBO должны (tm) всегда просто ускорять процесс.
источник
glDrawRangeElements
для рисования каждого отдельного объекта, или это неэффективно, как массивы вершин?glDrawRangeElements
несколько раз на каждом VBO с несколькими VBO вместо того, чтобы давать каждому объекту свое собственное VBO?Не совсем. Вершинные массивы являются основой для буферных объектов вершин. Только хранилище перемещено от клиента к стороне сервера.
Объедините меньшие наборы геометрии в большие VBO. Нет необходимости иметь один VBO для каждой партии геометрии. Вы можете идеально обратиться к подмножествам VBO для рендеринга. Используйте ненулевое смещение для параметра данных gl… Pointer.
Для этого есть флаги использования буфера GL_DYNAMIC_DRAW и GL_STREAM_DRAW.
Потому что нет никаких преимуществ. Данные геометрии должны быть переданы в графический процессор в любом случае. Использование обычного клиентского массива вершин по-прежнему будет вызывать передачу DMA в GPU, а в режиме немедленной обработки будет также создан пакет для первой передачи.
Нет абсолютно никакой пользы в том, чтобы не использовать VBO.
источник