Разница в glGenBuffers и glCreateBuffers

Учитывая, что мы используем OpenGL 4.5 или поддерживаем расширение GL_ARB_direct_state_access, у нас есть новая функция glCreateBuffers.

Эта функция имеет идентичную подпись glGenBuffers, но указывает:

возвращает n ранее неиспользуемые имена буферов в buffers, каждый из которых представляет новый объект буфера, инициализированный так, как если бы он был связан с неопределенной целью

glGenBuffers имеет следующую спецификацию:

Имена объектов буфера, возвращенные вызовом glGenBuffers, не возвращаются последующими вызовами, если только они не были удалены с помощью glDeleteBuffers.

Таким образом, любое имя буфера, возвращаемое glCreateBuffers, никогда не будет использоваться само по себе, но может использоваться glGenBuffers.

Кажется, что glCreateBuffers всегда будет создавать новые объекты буфера и возвращать их имена, а glGenBuffers будет создавать новые буферы только в том случае, если ранее не было удаленных буферов.

Какое преимущество имеет добавление этой функции?

Когда следует использовать glCreateBuffers над glGenBuffers?


P.S.
Я думаю, что это означает все glCreate* функции, добавленные GL_ARB_direct_state_access

Ответы

Ответ 1

То, что вы заметили здесь, в основном убирает API для обеспечения согласованности с созданием объекта Shader и Program. Они всегда генерировались и инициализировались одним вызовом и были единственной частью API, которая работала именно так. Каждый другой объект был зарезервирован с использованием glGen* (...) и позже инициализирован путем привязки зарезервированного имени к цели.

Фактически, перед GL 3.0 было допустимо пропустить glGen* (...) вообще и создать объект просто путем привязки уникального числа где-нибудь.

В GL 4.5 каждому типу объекта была предоставлена ​​функция glCreate* (...), которая генерирует и инициализирует их в одном вызове в GL 4.5. Эта методология прекрасно сочетается с Direct State Access, при изменении (в этом случае создании) объект не требует изменения (и потенциального восстановления) состояния привязки.


Многие объекты требуют целевой (например, текстуры) при использовании API таким образом, но объекты-буферы для всех целей и целей не имеют значения. Вот почему подпись API идентична. Когда вы создаете объект-буфер с этим интерфейсом, он "инициализируется так, как если бы он был связан с неопределенной целью". Это было бы полной бессмыслицей для большинства типов объектов в GL; им нужна цель для правильной их инициализации.

Основное внимание здесь заключается в том, что вы можете создать и настроить состояние для объекта в GL, не затрагивая какой-либо другой фрагмент кода, который ожидает, что объект, привязанный к определенной цели, останется неизменным. Для этого был создан Direct State Access, и это основная причина, по которой эти функции существуют.

В теории, как указывает Дари, инициализация объекта-буфера путем привязки его к конкретной цели потенциально дает подсказкам драйвера о его предполагаемом использовании. Я бы не стал вкладывать в нее много акций, но это так же, как и фактические флаги использования при вызове glBufferData (...); подсказка в лучшем случае.

Ответ 2

OpenGL 4.5 Спецификация - 6.1 Создание и привязка буфера:

Объект-буфер создается путем привязки имени, возвращаемого GenBuffers, к целевой буфер. Связывание осуществляется путем вызова

void BindBuffer (целевой объект перечисления, буфер uint);

цель должна быть одной из перечисленных целей в таблице 6.1. Если буферный объект с именем buffer не был ранее связанный, GL создает новый вектор состояния, инициализированный буфер памяти нулевого размера и содержащий все состояние и с одинаковые начальные значения, перечисленные в таблице 6.2.

Таким образом, разница между glGenBuffers и glCreateBuffers заключается в том, что glGenBuffers возвращает неиспользуемое имя, а glCreateBuffers также создает и инициализирует вектор состояния, описанный выше.


Использование:

Рекомендуется использовать glGenBuffers + glBindBuffer, потому что

GL может делать разные варианты выбора места хранения и макет на основе первоначальной привязки.

Так как в glCreateBuffers не задано начальное связывание, этот выбор невозможен.

Ответ 3

glCreateBuffers не имеет цели, потому что объекты буфера не печатаются. Первая цель привязки использовалась только как подсказка в OpenGL. И Хронос считал, что дает параметр glCreateBuffers a target, но они решили против него:

NamedBufferData (и соответствующая функция из исходного EXT) не включайте параметр < target. Могут ли реализации исходные предположения об использовании хранилища данных на основе этого параметр. Куда он пошел? Должны ли мы вернуть его?

RESOLVED: нет необходимости в целевом параметре для буфера. Implemetations [так в оригинале] не используйте предположения использования на основе параметра < target. Только один расширение поставщика делает так AMD_pinned_memory. [Sic] для последовательного подхода для указания использования буфера было бы добавить новый флаг для этого <flags> параметр BufferStorage.

Добавлен акцент.