Разница в glGenBuffers и glCreateBuffers

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

Эта функция имеет такую ​​же сигнатуру, что и glGenBuffers, но указывает:

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

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

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

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

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

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

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


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


person RamblingMad    schedule 05.08.2015    source источник
comment
Один говорит, что каждый представляет новый буферный объект, другой говорит, что никакие буферные объекты не связаны с возвращенными именами буферных объектов. Вы говорите, что glGenBuffers будет создавать новые буферы только в том случае, если нет предыдущих буферов, которые были удалены с тех пор, но glGenBuffers никогда не будет создавать новые буферы.   -  person Ben Voigt    schedule 05.08.2015
comment
Ах, так что тебе никогда не нужно звонить glBindBuffer, имеет смысл   -  person RamblingMad    schedule 05.08.2015
comment
@BenVoigt сделай ответ, чувак, это все, что мне нужно.   -  person RamblingMad    schedule 05.08.2015
comment
Но вам все равно нужно будет вызвать glBindBuffer, потому что инициализация, как если бы он был привязан к неуказанной цели, не очень полезен. Возможно, есть разница в том, какие операции разрешены до вызова glBindBuffer.   -  person Ben Voigt    schedule 05.08.2015
comment
@BenVoigt, но это полезно при использовании с glVertexArray*Buffer[s]   -  person RamblingMad    schedule 05.08.2015


Ответы (3)


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

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

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


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

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

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

person Andon M. Coleman    schedule 06.08.2015
comment
Многие объекты требуют цели На самом деле не у многих есть цели. Текстуры, объекты запроса и, если вы достаточно растянули определение цели, объекты шейдера. FBO привязаны к целям, но сами объекты не имеют целей. - person Nicol Bolas; 10.05.2019

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

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

void BindBuffer (цель перечисления, буфер uint);

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

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


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

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

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

Поскольку в glCreateBuffers начальная привязка не указана, этот выбор сделать нельзя.

person dari    schedule 05.08.2015
comment
Рекомендуется использовать glGenBuffers + glBindBuffer, потому что нет. Как ясно указано в расширении ARB_direct_state_access, никого на самом деле не заботит, как буфер изначально связан. Именно поэтому glCreateBuffers не берет цель, а glCreateTextures делает. Так что ваша рекомендация неуместна. - person Nicol Bolas; 22.06.2016
comment
@NicolBolas Я бы продвинул ваш комментарий к альтернативному ответу, потому что, хотя ответ Дари в основном правильный, его замечание об использовании сбивает с толку и, вероятно, основано на мнении. - person Michael IV; 25.11.2017

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

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

РЕШЕНО: Нет необходимости в целевом параметре для буфера. Реализации [sic] не предполагают использование на основе параметра ‹target>. Только одно расширение поставщика делает это AMD_pinned_memory. [Sic] для последовательного подхода к определению использования буфера будет добавление нового флага для этого параметра ‹flags> в BufferStorage.

Акцент добавлен.

person Nicol Bolas    schedule 25.11.2017