При настройке расположения атрибутов для программы шейдера OpenGL вы сталкиваетесь с двумя вариантами:
glBindAttribLocation () перед связыванием, чтобы явно определить местоположение атрибута.
или же
glGetAttribLocation () после связывания, чтобы получить автоматически назначенное местоположение атрибута.
Какая утилита позволяет использовать одно поверх другого?
И какой из них предпочтительнее на практике?
glBindAttribLocation
свой графический движок, который отлично работал в Linux. Когда я портировал в окна, он использовал мои нормали в качестве вершин - мне пришлось явно указать ему порядок переменных в моем шейдере,glBindAttribLocation
чтобы заставить его работать ...Ответы:
Я знаю одну вескую причину предпочесть явное определение местоположения.
Учтите, что вы храните свои геометрические данные в объектах Vertex Array Objects. Для данного объекта вы создаете VAO таким образом, чтобы индексы соответствовали, например:
Теперь представьте, что вы хотите нарисовать один объект двумя разными шейдерами . Один шейдер требует в качестве входных данных позиции и нормальных данных , другой - позиции и координаты текстуры .
Если вы скомпилируете эти шейдеры, вы заметите, что первый шейдер будет ожидать позиции с индексом атрибута 0 и нормали с индексом 1. Другой будет ожидать позиций с 0, а координаты текстуры с 1.
Цитата https://www.opengl.org/wiki/Vertex_Shader :
Это означает, что вы не сможете использовать свой VAO с обоими шейдерами. Вместо того, чтобы иметь один VAO для, скажем, объекта, вам понадобится - в худшем случае - отдельный VAO для каждого объекта на шейдер .
Заставив шейдеры использовать собственное соглашение о нумерации атрибутов,
glBindAttribLocation
можно легко решить эту проблему - все, что вам нужно сделать, это сохранить согласованную связь между атрибутами и их установленными идентификаторами и заставить шейдеры использовать это соглашение при связывании.(На самом деле это не большая проблема, если вы не используете отдельные VAO, но все же может сделать ваш код более понятным.)
Кстати:
В OpenGL / GLSL 3.3 есть третий вариант: указать местоположение непосредственно в коде шейдера . Выглядит это так:
Но этого нет в языке шейдеров GLSL ES.
источник
Другой ответ заключается в том, что glGetAttribLocation возвращает данные вызывающей стороне, что означает, что он неявно требует сброса конвейера. Если вы вызываете его сразу после компиляции программы, вы, по сути, заставляете асинхронную компиляцию происходить синхронно.
источник
glGetUniformLocation
; актуально ли это конкретное соображение?Третий вариант, то есть
layout(location=0) in vec4 position;
в коде шейдера, теперь доступен в OpenGL ES 3.0 / GLSL 300 es. Но только для входных переменных вершинного шейдера.источник