Signatur
Beschreibung
Die Methode bindVertexArrayOES() gehört zur WebGL-1-Erweiterung OES_vertex_array_object. Sie macht ein Vertex Array Object (VAO) zum aktuell gebundenen VAO. Ein VAO speichert den kompletten Zustand der Vertex-Attribute: welche Attribute mit enableVertexAttribArray() aktiviert sind, die Einstellungen aus vertexAttribPointer() (inklusive des dabei gebundenen ARRAY_BUFFER) sowie den gebundenen ELEMENT_ARRAY_BUFFER.
Der typische Ablauf: Einmalig beim Initialisieren ein VAO mit createVertexArrayOES() erzeugen, binden, Puffer und Attribute konfigurieren und anschließend wieder lösen. Beim Zeichnen genügt dann ein einziger Aufruf von bindVertexArrayOES(vao) statt vieler bindBuffer-/vertexAttribPointer-Aufrufe. Das reduziert den Overhead pro Draw-Call deutlich, besonders bei vielen unterschiedlichen Meshes.
Wird null übergeben, wird das Standard-VAO des Kontexts wieder gebunden. Das ist wichtig, damit nachfolgender Code, der keine VAOs kennt, nicht versehentlich das Zustandsobjekt eines Meshes verändert.
In WebGL 2 ist die Funktionalität fest eingebaut und heißt WebGL2RenderingContext.bindVertexArray() – die Erweiterung wird dort nicht benötigt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $arrayObject Pflicht | WebGLVertexArrayObjectOES | null | Das zu bindende VAO, erzeugt mit createVertexArrayOES(). null bindet wieder das Standard-VAO. |
Rückgabewert
undefined).Beispiele
VAO einrichten und beim Zeichnen binden
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
const ext = gl.getExtension('OES_vertex_array_object');
if (!ext) throw new Error('OES_vertex_array_object nicht verfügbar');
// Minimales Shader-Programm
const vsSrc = 'attribute vec2 aPos; void main(){ gl_Position = vec4(aPos, 0.0, 1.0); }';
const fsSrc = 'precision mediump float; void main(){ gl_FragColor = vec4(1.0, 0.5, 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, vsSrc));
gl.attachShader(program, compile(gl.FRAGMENT_SHADER, fsSrc));
gl.linkProgram(program);
const aPos = gl.getAttribLocation(program, 'aPos');
// VAO anlegen und Zustand aufzeichnen
const vao = ext.createVertexArrayOES();
ext.bindVertexArrayOES(vao);
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);
gl.enableVertexAttribArray(aPos);
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
ext.bindVertexArrayOES(null); // Aufzeichnung beenden
// Zeichnen: ein Bind genügt
gl.useProgram(program);
ext.bindVertexArrayOES(vao);
gl.drawArrays(gl.TRIANGLES, 0, 3);
ext.bindVertexArrayOES(null);
Mehrere Meshes mit eigenem VAO rendern
// Annahme: gl, ext, program wie oben; meshes enthält { vao, count }
const render = (meshes) => {
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
for (const { vao, count } of meshes) {
ext.bindVertexArrayOES(vao);
gl.drawArrays(gl.TRIANGLES, 0, count);
}
ext.bindVertexArrayOES(null);
};
Fallback: WebGL 2 oder Erweiterung
const canvas = document.createElement('canvas');
const gl2 = canvas.getContext('webgl2');
let bindVAO, createVAO;
if (gl2) {
createVAO = () => gl2.createVertexArray();
bindVAO = (vao) => gl2.bindVertexArray(vao);
} else {
const gl = canvas.getContext('webgl');
const ext = gl.getExtension('OES_vertex_array_object');
createVAO = () => ext.createVertexArrayOES();
bindVAO = (vao) => ext.bindVertexArrayOES(vao);
}
const vao = createVAO();
bindVAO(vao);
console.log('VAO gebunden:', vao !== null);
bindVAO(null);
// Wichtig · Fallstricke
- Zustand vergessen zu lösen: Bleibt ein VAO gebunden, landen spätere
vertexAttribPointer()- oderbindBuffer(ELEMENT_ARRAY_BUFFER, …)-Aufrufe in diesem VAO und überschreiben dessen Konfiguration. Nach dem Einrichten daher immerbindVertexArrayOES(null)aufrufen. - ARRAY_BUFFER vs. ELEMENT_ARRAY_BUFFER: Die
ARRAY_BUFFER-Bindung selbst gehört nicht zum VAO-Zustand – gespeichert wird nur der Puffer, der beimvertexAttribPointer()-Aufruf gebunden war. DieELEMENT_ARRAY_BUFFER-Bindung ist dagegen Teil des VAO. - Kontextübergreifend: Das VAO muss aus derselben Erweiterungsinstanz und demselben Kontext stammen, sonst entsteht ein
INVALID_OPERATION-Fehler. Ein mitdeleteVertexArrayOES()gelöschtes VAO darf nicht mehr gebunden werden. - Kompatibilität: Die Erweiterung ist in praktisch allen WebGL-1-Implementierungen verfügbar, muss aber per
gl.getExtension('OES_vertex_array_object')aktiviert werden. In WebGL-2-Kontexten ist sie nicht vorhanden – dortbindVertexArray()verwenden. - Nach einem Kontextverlust (
webglcontextlost) sind alle VAOs ungültig und müssen neu erzeugt werden.