Beim Einrichten von Attributpositionen für ein OpenGL-Shader-Programm stehen Ihnen zwei Optionen zur Verfügung:
glBindAttribLocation () vor dem Verknüpfen, um einen Attributspeicherort explizit zu definieren.
oder
glGetAttribLocation () nach dem Verknüpfen, um einen automatisch zugewiesenen Attributspeicherort zu erhalten.
Was ist das Dienstprogramm für die Verwendung übereinander?
Und welches, wenn überhaupt, wird in der Praxis bevorzugt?
glBindAttribLocation
meine Grafik-Engine zu verwenden, die unter Linux gut funktioniert hat. Als ich auf Windows portierte, verwendete es meine Normalen als Eckpunkte - ich musste ihm explizit die Reihenfolge der Variablen in meinem Shader mitteilenglBindAttribLocation
, damit es funktioniert ...Antworten:
Ich kenne einen guten Grund, eine explizite Standortdefinition zu bevorzugen .
Beachten Sie, dass Sie Ihre Geometriedaten in Vertex-Array-Objekten speichern . Für ein bestimmtes Objekt erstellen Sie eine VAO so, dass die Indizes beispielsweise Folgendes entsprechen:
Stellen Sie sich nun vor, Sie möchten ein Objekt mit zwei verschiedenen Shadern zeichnen . Ein Shader benötigt Positions- und Normaldaten als Eingabe, der andere - Positionen und Texturkoordinaten .
Wenn Sie diese Shader kompilieren, werden Sie feststellen, dass der erste Shader die Positionen bei Attributindex 0 und Normalen bei 1 erwartet. Der andere erwartet Positionen bei 0, aber Texturkoordinaten bei 1.
Zitieren von https://www.opengl.org/wiki/Vertex_Shader :
Dies bedeutet, dass Sie Ihr VAO nicht mit beiden Shadern verwenden können. Anstatt beispielsweise eine VAO pro Objekt zu haben, benötigen Sie im schlimmsten Fall eine separate VAO pro Objekt und Shader .
Wenn Sie die Shader dazu zwingen, Ihre eigene Attributnummerierungskonvention zu verwenden,
glBindAttribLocation
kann dieses Problem leicht gelöst werden. Sie müssen lediglich eine konsistente Beziehung zwischen Attributen und ihren etablierten IDs beibehalten und die Shader zwingen, diese Konvention beim Verknüpfen zu verwenden.(Das ist kein großes Problem, wenn Sie keine separaten VAOs verwenden, aber Ihren Code möglicherweise klarer machen.)
Übrigens:
In OpenGL / GLSL 3.3 gibt es eine dritte Option: Geben Sie den Speicherort direkt im Shader-Code an . Es sieht aus wie das:
Dies ist jedoch in der GLSL ES-Shader-Sprache nicht vorhanden.
quelle
Eine andere Antwort hier ist, dass glGetAttribLocation Daten an den Aufrufer zurückgibt, was bedeutet, dass implizit ein Pipeline-Flush erforderlich ist. Wenn Sie es direkt nach dem Kompilieren Ihres Programms aufrufen, erzwingen Sie im Wesentlichen die synchrone Kompilierung.
quelle
glGetUniformLocation
sowieso anrufen . Ist diese besondere Überlegung noch relevant?Die dritte Option, dh
layout(location=0) in vec4 position;
im Shader-Code, ist jetzt in OpenGL ES 3.0 / GLSL 300 es verfügbar. Nur für Vertex-Shader-Eingabevariablen.quelle