Per-Vertex Attribute
← Uniforme Parameter | ● | Interpolierte Parameter →
Parameter, die je Vertex spezifiziert werden, nennt man auch einfach nur Attribute. Diese können ausschließlich im Vertex-Shader benutzt werden.
Selbstdefinierte Attribute
- Man definiert im Vertex-Shader eine (globale) Variable, die einen Wert enthalten soll:
attribute vec4 myAttributeName; - Man definiert die Werte der Attribute jeweils vor der Spezifikation des Vertex:
glVertexAttrib4f (<Nummer>, v1, v2, v3, v4);
Dafür benötigt man wie bei uniform
s die Location.
Frühere, zu uniform konsistente Variante
- Man holt sich die Nummer der Variablen mit
glGetAttribLocation (<Program-Handle>, <Variablenname als String>)
Dieses Verfahren ist allerdings veraltet, da es nur mit zusammen mit den legacy Attributen wie gl_Vertex funktioniert.
Beispiel (legacy):
- Shader:
#version 120
attribute vec4 add;
void main () {
gl_Position = gl_Vertex + add;
} - Initialisierung, nach Programmerstellung:
GLint attrib_add = glGetAttribLocation (prog, "add");
if (attrib_add < 0)
lglError ("Can't find attribute 'add'"); - Zeichnen - ursprünglich im Direct Mode:
glBegin (GL_POINTS);
glVertexAttrib4f (attrib_add, 0, 1, 2, 3);
glVertex4f (1, 1, 1, 1);
glEnd ();
Wird im Beispiel den Vertex (1, 2, 3, 4) an die Rasterisierungseinheit übergeben.
Vordefinierte (Legacy) Attribute
Es gibt ein paar Attribute, die vordefiniert sind, die über spezielle Funktionen gesetzt werden, und die über fest definierte Variablennamen im Shader zugreifbar sind.
Die Vertex-Koordinaten sind nichts anderes als ein Attribut.
- Vertex:
glVertex*()
zum setzen,gl_Vertex
im Shader - Farbe:
glColor*()
zum setzen,gl_Color
im Shader - Normale:
glNormal3f()
zum setzen,gl_Normal
im Shader - Textur-Koordinaten:
glTexCoord*()
zum setzen,gl_MultiTexCoord0
im Shader
… und auch die legacy uniform Projektions- und Modelview-Matrix gl_ProjectionMatrix
, gl_ModelViewMatrix
und gl_ModelViewProjectionMatrix
.
Nachteil
In neueren GLSL Versionen sind diese so unter Umständen gar nicht mehr vorhanden! Speziell unter MacOS funktionieren sie so in VBOs nicht mehr. Dort muss man eine alternative Herangehensweise benutzen, und die Location aller Attribute (inklusive dem Vertex!) explizit auswählen und mit glBindAttribLocation()
binden.
Modernes Verfahren über Bindung
Dazu nummeriert man (selber!) alle Attribute beginnend mit 0, ein Index pro 4er-Vektor. Matrizen zählen dabei als 4 Vektoren. Die Vertex-Koordinaten haben traditionell den Wert 0, und funktionieren nur damit über die Legacy-Methoden.
- Shader:
#version 120
attribute vec4 vertex_position;
attribute vec4 add;
void main () {
gl_Position = vertex_position + add;
} - Initialisierung, nach Shadererstellung, aber vor dem Linken des Shader-Programms:
:
glBindAttribLocation (prog, 1, "add");
- Zeichnen - ursprünglich im Direct Mode:
glBegin (GL_POINTS);
glVertexAttrib4f (1, 0, 1, 2, 3);
glVertex4f (1, 1, 1, 1); // alternativ: glVertexAttrib4f (0, 1, 1, 1, 1);
glEnd ();
Wird im Beispiel den Vertex (1, 2, 3, 4) an die Rasterisierungseinheit übergeben.
In VBOs (siehe späteres Kapitel) wird das einfacher.
Framework
- Vertex:
vertex_position
im Shader
lglVertex()
- Farbe:
vertex_color
im Shader
lglColor()
- Normale:
vertex_normal
im Shader
lglNormal()
- Textur-Koordinaten:
vertex_texcoord
im Shader
lglTexCoord()
- Eigene:
vertex_attribute1
im Shader
lglAttribute (vec4(.1,0,0,0), 1);
Siehe auch Native Standard-Codesequenz.