Znam jeden dobry powód, by preferować jednoznaczną definicję lokalizacji.
Weź pod uwagę, że przechowujesz dane geometryczne w Vertex Array Objects. Dla danego obiektu tworzysz VAO w taki sposób, aby indeksy odpowiadały np .:
- indeks 0 : pozycje,
- indeks 1 : normalne,
- indeks 2 : texcoords
Teraz zastanów się, czy chcesz narysować jeden obiekt za pomocą dwóch różnych shaderów . Jeden moduł cieniujący wymaga danych dotyczących pozycji i normalnych jako danych wejściowych, a drugi - pozycji i współrzędnych tekstur .
Jeśli skompilujesz te moduły cieniujące, zauważysz, że pierwszy moduł cieniujący będzie oczekiwał pozycji o indeksie atrybutu 0, a normalnych o wartości 1. Drugi będzie oczekiwał pozycji na 0, ale współrzędnych tekstur na 1.
Cytując https://www.opengl.org/wiki/Vertex_Shader :
Automatyczne przypisywanie
Jeśli żadna z dwóch poprzednich metod nie przypisuje wejścia do indeksu atrybutu, indeks jest automatycznie przypisywany przez OpenGL, gdy program jest połączony. Przypisany indeks jest całkowicie dowolny i może być inny dla różnych programów, które są połączone, nawet jeśli używają dokładnie tego samego kodu Vertex Shader.
Oznacza to, że nie byłbyś w stanie używać swojego VAO z obydwoma shaderami. Zamiast jednego VAO na, powiedzmy, obiekt, potrzebujesz - w najgorszym przypadku - oddzielnego VAO na obiekt na moduł cieniujący .
Zmuszenie shaderów do używania własnej konwencji numerowania atrybutów poprzez glBindAttribLocation
może łatwo rozwiązać ten problem - wszystko, co musisz zrobić, to zachować spójną relację między atrybutami a ich ustalonymi identyfikatorami i zmusić shadery do korzystania z tej konwencji podczas łączenia.
(To nie jest duży problem, jeśli nie używasz oddzielnych VAO, ale mimo to może sprawić, że kod będzie bardziej przejrzysty).
BTW:
Podczas konfigurowania lokalizacji atrybutów dla programu cieniującego OpenGL masz do wyboru dwie opcje
W OpenGL / GLSL 3.3 jest trzecia opcja: Określ lokalizację bezpośrednio w kodzie modułu cieniującego . To wygląda tak:
layout(location=0) in vec4 position;
Ale to nie jest obecne w języku shaderów GLSL ES.
glBindAttribLocation
w moim silniku graficznym, który ładnie działał na Linuksie. Kiedy przeportowałem do systemu Windows, używał moich normalnych jako wierzchołków - musiałem wyraźnie powiedzieć mu kolejność zmiennych w moim module cieniującym przezglBindAttribLocation
, aby działał ...