Start · Sprachen · JavaScript · Referenz · WebGLRenderingContext.disableVertexAttribArray()

WebGLRenderingContext.disableVertexAttribArray()

Methode

Schaltet das generische Vertex-Attribut-Array an der Position <code>index</code> aus, sodass der Shader stattdessen einen konstanten Attributwert erhält.

seit JavaScript WebGL 1.0 – Baseline: alle modernen Browser Kategorie: webapi

Signatur

WebGLRenderingContext.prototype.disableVertexAttribArray(index)

Beschreibung

Mit disableVertexAttribArray() deaktivierst du das Vertex-Attribut-Array an einem bestimmten Attribut-Index. Solange ein Array aktiv ist, liest WebGL die Werte pro Vertex aus dem Puffer, der über vertexAttribPointer() gebunden wurde. Nach dem Deaktivieren liest der Vertex-Shader für dieses Attribut bei jedem Vertex denselben konstanten Wert. Diesen Wert setzt du mit vertexAttrib1f() bis vertexAttrib4fv().

Das Gegenstück ist enableVertexAttribArray(). Anfangs sind alle Attribut-Arrays deaktiviert. Die Methode ist vor allem in zwei Fällen nützlich:

  • Konstante Attribute: Ein Objekt soll zum Beispiel eine einheitliche Farbe bekommen, obwohl der Shader ein Farbattribut pro Vertex erwartet.
  • Aufräumen zwischen Draw-Calls: Nutzen verschiedene Objekte unterschiedliche Attribute, verhinderst du so, dass ein noch aktives Attribut auf einen unpassenden oder zu kleinen Puffer zeigt.

In WebGL 2 (und in WebGL 1 mit der Erweiterung OES_vertex_array_object) wird der Aktivierungszustand im gerade gebundenen Vertex Array Object (VAO) gespeichert. Der Aufruf wirkt sich also nur auf das aktuell gebundene VAO aus.

Parameter

Name Typ Default Beschreibung
$index Pflicht GLuint (number) Index des Vertex-Attributs, das deaktiviert werden soll. Meist ermittelt mit gl.getAttribLocation(program, name) oder im Shader fest vergeben (layout(location = n) in GLSL ES 3.00).

Rückgabewert

Typ
void
Beschreibung
Die Methode gibt keinen Wert zurück (undefined).

Beispiele

Attribut-Array aktivieren und nach dem Zeichnen wieder deaktivieren

const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');

const vsSource = `
  attribute vec2 aPosition;
  void main() { gl_Position = vec4(aPosition, 0.0, 1.0); }
`;
const fsSource = `
  precision mediump float;
  void main() { gl_FragColor = vec4(1.0, 0.4, 0.0, 1.0); }
`;

const compile = (type, src) => {
  const s = gl.createShader(type);
  gl.shaderSource(s, src);
  gl.compileShader(s);
  return s;
};

const program = gl.createProgram();
gl.attachShader(program, compile(gl.VERTEX_SHADER, vsSource));
gl.attachShader(program, compile(gl.FRAGMENT_SHADER, fsSource));
gl.linkProgram(program);
gl.useProgram(program);

const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0.8, -0.8, -0.8, 0.8, -0.8]), gl.STATIC_DRAW);

const loc = gl.getAttribLocation(program, 'aPosition');
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);

gl.drawArrays(gl.TRIANGLES, 0, 3);

// Aufräumen: Attribut wieder deaktivieren
gl.disableVertexAttribArray(loc);
console.log(gl.getVertexAttrib(loc, gl.VERTEX_ATTRIB_ARRAY_ENABLED));
false

Konstante Farbe statt Farbe pro Vertex

// Annahme: Programm mit 'attribute vec4 aColor;' ist aktiv
const colorLoc = gl.getAttribLocation(program, 'aColor');

// Objekt A: Farben pro Vertex aus dem Puffer
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.enableVertexAttribArray(colorLoc);
gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, vertexCountA);

// Objekt B: einheitlich blau – Array aus, konstanten Wert setzen
gl.disableVertexAttribArray(colorLoc);
gl.vertexAttrib4f(colorLoc, 0.1, 0.3, 1.0, 1.0);
gl.drawArrays(gl.TRIANGLES, 0, vertexCountB);

Hilfsfunktion: alle Attribute zurücksetzen

const resetAttribArrays = (gl) => {
  const max = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
  for (let i = 0; i < max; i++) {
    gl.disableVertexAttribArray(i);
  }
  return max;
};

console.log(`${resetAttribArrays(gl)} Attribute deaktiviert`);
16 Attribute deaktiviert

// Wichtig · Fallstricke

  • Ungültiger Index: Ist index größer oder gleich gl.MAX_VERTEX_ATTRIBS, erzeugt der Aufruf den Fehler gl.INVALID_VALUE. Eine Exception wird nicht geworfen, prüfe daher bei Bedarf gl.getError().
  • -1 von getAttribLocation: Wurde ein Attribut vom Shader-Compiler wegoptimiert, liefert getAttribLocation() den Wert -1. Dieser Wert wird als GLuint zu 4294967295 umgewandelt und löst INVALID_VALUE aus. Prüfe den Index deshalb vor dem Aufruf.
  • Attribut 0: Manche ältere Desktop-Treiber waren langsam oder zeichneten nichts, wenn Attribut 0 deaktiviert war. Belege Attribut 0 am besten immer mit einem aktiven Array, zum Beispiel über bindAttribLocation(program, 0, 'aPosition').
  • VAOs: Mit gebundenem VAO (WebGL 2 oder OES_vertex_array_object) gilt der Zustand nur für dieses VAO. Ein Deaktivieren „zum Aufräumen“ ist dann meist überflüssig.
  • Standardwert: Der konstante Standardwert eines deaktivierten Attributs ist (0, 0, 0, 1).
  • Die Methode gibt es in allen Browsern mit WebGL-Unterstützung. In WebGL 2 steht sie auch auf WebGL2RenderingContext zur Verfügung.