Computergrafik

Per-Vertex Attribute

Uniforme Parameter | | Normalen

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 uniforms 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, welches wie folgt gesetzt wird:

  • Vertex: glVertex*(), gl_Vertex im Shader
  • Farbe: glColor*(), gl_Color im Shader
  • Normale: glNormal3f(), gl_Normal im Shader
  • Textur-Koordinaten: glTexCoord*(), 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, 0, "vertex_position");
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.

Uniforme Parameter | | Normalen

Options: