Несколько UBO без явного указания индекса точки привязки
Я изучаю объекты унифицированного буфера OpenGL и буферы хранения шейдеров. Я думаю, что этот вопрос относится к ним обоим, но давайте сосредоточимся только на БП.
Похоже, что в руководствах говорится, что "индекс блока" и "индекс точки привязки" - это разные вещи, и если у меня в шейдере более одного UBO, мне нужно указать индекс привязки
layout(binding = 0) uniform first_buffer {...};
layout(binding = 1) uniform second_buffer {...};
У меня создается впечатление, что индекс блока определяется компоновщиком и может быть прочитан из glGetUniformBlockIndex
, но индекс точки привязки должен быть жестко задан произвольным binding=N
в макете, и соответствующий glBindBufferBase(GL_UNIFORM_BUFFER, N, ubo_handle)
, который мне кажется хрупким и неприятным.
В чем разница между блочным индексом и точкой привязки?
Могу я опустить binding=N
в макете? Что тогда происходит сglBindBufferBase
?
Это все то же самое для SSBO?
1 ответ
См. Спецификацию профиля ядра API OpenGL 4.6 - 7.6 Унифицированные переменные
Именованные унифицированные блоки, как описано в спецификации языка затенения OpenGL, хранят единые значения в хранилище данных буферного объекта, соответствующего унифицированному блоку. Таким блокам присваивается единый блочный индекс.
Блочный индекс - это "дескриптор" активного программного ресурса шейдерной программы. Если у вас есть разные программы шейдеров с "одним и тем же" равномерным блоком, они могут иметь разные индексы буфера.
Буфер связан с единым блоком шейдерной программы точкой привязки (например, в шейдере с помощью квалификатора макета точки привязки). С одной стороны, единый блок (индекс) связан с точкой привязки, а с другой стороны, буфер привязан к точке привязки ( glBindBufferBase
). Таким образом, один буфер может быть привязан к единым блокам разных программ.
Хотя индекс буфера является фиксированным и не может быть изменен после связывания программы, точка привязки является динамическим значением и может быть изменена с помощью glUniformBlockBinding
. Когда программа связана, то точка привязки инициализируется 0 или значением, которое задается квалификатором макета точки привязки.
Этот принцип тот же, что и для объекта буфера хранилища шейдеров.
Связанные вопросы:
Разница между glBindBuffer и glBindBufferBase
Безопасно ли использовать индекс блока в качестве точки привязки для UniformBufferObject, ShaderStorageBufferObjects и т. Д.?
Как мне запросить выравнивание / шаг для структуры SSBO?