OpenGL Uniform Buffer путаница - PullRequest
       0

OpenGL Uniform Buffer путаница

6 голосов
/ 10 сентября 2011

Может кто-нибудь рассказать мне о, казалось бы, бесполезно усложненных единообразных буферах? Я прочитал раздел в OpenGL Superbible 5, я просмотрел несколько примеров в блогах, прочитал официальную спецификацию и до сих пор не понимаю.

В частности, во всех примерах, похоже, для начала требуется программа шейдера, чтобы изначально настроить единый буфер с помощью glGetActiveUniformsiv. Я не понимаю этого. Почему интерфейс не позволяет вам определять структуру, не обращаясь к шейдерной программе, проверяя форматы буфера / с программой во время соединения?

Во-вторых, если я получу структуру структуры из одной программы, предполагая, что структура структуры одинакова для всех программ, которые используют набор униформ, будет ли структура иметь одинаковые смещения, размеры данных и т. Д.? Я бы предположил, что так.

В-третьих, я не понимаю обязательных пунктов. Я должен вызвать glBindBufferBase с индексом, а затем вызвать glUniformBlockBinding с индексом блока и индексом, который я передал в glBindBufferBase. У меня проблемы с визуализацией, что именно здесь происходит. В Superbible нет ясности, как и в спецификации и в образцах, которые я видел.

1 Ответ

11 голосов
/ 10 сентября 2011
  1. Почему именно вы хотите?Лично, если у вас нет серьезной проблемы с нехваткой данных и вам нужен каждый байт, я не вижу причин использовать что-либо кроме std140.Это делает код , поэтому намного чище.

    Однако, если вы намерены избегать std140, продолжайте читать.

  2. Спецификация полностью объяснила это: все это в квалификаторах макета.

    Существует ровно 3 квалификатора макета: packed, shared и std140.packed означает, что реализация свободна в организации всего, что она хочет.Это включает в себя удаление униформы, которую текущая программа не использует.Таким образом, макет определяется реализацией, и некоторые униформы в этом макете могли быть оптимизированы.

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

    Чтобы ответить на ваш первый вопрос, вы можете, если захотите, создать поддельную программу с макетом shared.Вы можете использовать его только для запроса макета унифицированного блока.Затем, если макет согласован в других программах (с макетом shared), макеты будут одинаковыми.Таким образом, для него не требуется специальный API.

    std140, однако означает, что компоновка унифицированного блока явно определяется реализацией OpenGL, байт за байтом.Это неявно позволяет совместное использование, так как два идентичных единообразных блока в соответствии с этой спецификацией будут иметь одинаковое расположение.А так как реализация не может оптимизировать униформу в блоке std140, все идеально.

    Опять же, почти нет причин избегать std140.Только если у вас очень, очень жесткие ограничения памяти.

  3. Это точный тот же механизм, что и для текстур.Единственное отличие состоит в том, что одинаковые имена блоков сами по себе не являются униформой.

    Объекты текстуры связаны с единицами изображения текстуры , используя glActiveTexture(GL_TEXTURE0 + i);glBindTexture(), где i - индекс единицы изображения текстуры.Теперь вам нужно указать шейдеру, какой сэмплер использует этот блок изображения.Однако OpenGL не позволяет вам связывать напрямую с именем;Вы должны преобразовать имя сэмплера в местоположение индекса.Таким образом, вы получаете единое местоположение для конкретного сэмплера с glGetUniformLocation.Если у вас есть единое местоположение, вы можете связать единицу изображения текстуры с этим местоположением, вызвав glUniform1i(loc, i), где снова i - это единица текстуры текстуры, к которой вы привязали текстуру.

    Связаны объекты с единым буферомна точки привязки к унифицированному буферу , используя glBindBufferRange(GL_UNIFORM_BUFFER, i, ...), где i - точка привязки к унифицированному буферу.Теперь вам нужно указать шейдеру, какой унифицированный блок использует эту точку привязки.Однако OpenGL не позволяет вам связывать напрямую с именем;Вы должны преобразовать единообразный блок в указатель.Таким образом, вы получаете индекс для определенного единообразного блока с glGetUniformBlockIndex.Получив индекс, вы можете связать точку привязки унифицированного буфера с этим индексом, вызвав glUniformBlockBinding(program, index, i), где снова i - это точки привязки унифицированного буфера, к которым вы привязали унифицированный буфер.

    Видите?Точно так же.Они используют разные термины, но структурно они одинаковы.Если вам нужна картинка, вы можете найти более подробное обсуждение , включающее диаграмму здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...