Явная и автоматическая привязка расположения атрибутов для шейдеров OpenGL - PullRequest
73 голосов
/ 08 января 2011

При настройке расположения атрибутов для шейдерной программы OpenGL вы сталкиваетесь с двумя вариантами:

glBindAttribLocation () перед установкой ссылки для явного определения расположения атрибута.

или

glGetAttribLocation () после связывания для получения автоматически назначенного местоположения атрибута.

Какая утилита для использования одного над другим?

А какой, если таковой имеется, предпочтителен на практике?

Ответы [ 3 ]

87 голосов
/ 09 января 2011

Я знаю одну вескую причину, чтобы предпочесть явное определение местоположения.

Учтите, что вы храните ваши геометрические данные в объектах массива вершин. Для данного объекта вы создаете VAO таким образом, чтобы индексы соответствовали, например:

  • index 0 : позиции,
  • index 1 : нормали,
  • index 2 : texcoords

Теперь рассмотрим, что вы хотите нарисовать один объект с двумя разными шейдерами .Один шейдер требует позиции и нормальных данных в качестве входных данных, другой - позиции и координаты текстуры .

Если вы скомпилируете эти шейдеры, вы заметите, что первый шейдер будетожидайте позиции с индексом атрибута 0 и нормали на 1. Другой будет ожидать позиции с 0, а координаты текстуры на 1.

Цитирование https://www.opengl.org/wiki/Vertex_Shader:

Автоматическое назначение

Если ни один из предыдущих двух методов не назначает вход для индекса атрибута, то индекс автоматически назначается OpenGL, когда программа связана.Присвоенный индекс является совершенно произвольным и может отличаться для разных связанных программ, даже если они используют один и тот же код вершинного шейдера.

Это означает, что вы не сможетеиспользуйте ваш VAO с обоими шейдерами. Вместо одного VAO на, скажем, объект, вам понадобится - в худшем случае - отдельный VAO на объект на шейдер .

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

(Это не очень большая проблема, если вы не используете отдельные VAO, но все же можете сделать ваш код более понятным.)


Кстати:

При настройке местоположений атрибутов для шейдерной программы OpenGL вы сталкиваетесь с двумя вариантами

В OpenGL / GLSL 3.3 есть третий вариант: указать местоположениепрямо в код шейдера .Это выглядит так:

layout(location=0) in vec4 position;

Но этого нет в языке шейдеров GLSL ES.

17 голосов
/ 20 февраля 2013

Другой ответ здесь заключается в том, что glGetAttribLocation возвращает данные вызывающей стороне, что означает, что неявно требуется очистка конвейера. Если вы вызываете его сразу после компиляции вашей программы, вы по существу заставляете асинхронную компиляцию выполняться синхронно.

8 голосов
/ 30 июня 2014

Третий параметр, т.е. layout(location=0) in vec4 position; в коде шейдера, теперь доступен в OpenGL ES 3.0 / GLSL 300 es.Только для входных переменных вершинного шейдера.

...