Signatur
Beschreibung
bufferData() reserviert GPU-Speicher für das Pufferobjekt, das gerade mit bindBuffer() an das angegebene Ziel gebunden ist. Übergibt man eine Zahl, wird ein mit Nullen gefüllter Speicher dieser Größe (in Bytes) angelegt. Übergibt man ein ArrayBuffer, eine ArrayBufferView (z. B. Float32Array) oder ein SharedArrayBuffer, werden die Daten direkt in den Puffer kopiert.
Typische Einsatzfälle sind das Hochladen von Vertex-Positionen, Normalen und Texturkoordinaten (gl.ARRAY_BUFFER), von Indizes (gl.ELEMENT_ARRAY_BUFFER) und in WebGL 2 zusätzlich von Uniform-Blöcken (gl.UNIFORM_BUFFER), Transform-Feedback-Ausgaben oder Pixel-Pack-/Unpack-Puffern.
Neu gegenüber WebGL 1 ist die Überladung mit srcOffset und length: Damit lässt sich nur ein Ausschnitt einer ArrayBufferView hochladen, ohne vorher per subarray() eine neue Sicht anzulegen. Beide Angaben zählen in Elementen des Typed Arrays, nicht in Bytes.
Der Parameter usage ist ein Hinweis an den Treiber, wie oft die Daten geändert und gelesen werden. Er beeinflusst nur die Leistung, nicht das Verhalten. Sollen Daten später teilweise aktualisiert werden, legt man den Puffer einmal mit bufferData() an und nutzt danach bufferSubData(), das keinen neuen Speicher reserviert.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | GLenum | Bindungsziel: gl.ARRAY_BUFFER, gl.ELEMENT_ARRAY_BUFFER, gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, gl.TRANSFORM_FEEDBACK_BUFFER, gl.UNIFORM_BUFFER, gl.PIXEL_PACK_BUFFER oder gl.PIXEL_UNPACK_BUFFER. |
|
| $sizeOrSrcData Pflicht | GLsizeiptr | ArrayBuffer | ArrayBufferView | SharedArrayBuffer | null | Entweder die Größe des Speichers in Bytes (wird mit Nullen gefüllt) oder die Quelldaten, die in den Puffer kopiert werden. Bei null wird ein Puffer der Größe 0 angelegt. |
|
| $usage Pflicht | GLenum | Nutzungshinweis: gl.STATIC_DRAW, gl.DYNAMIC_DRAW, gl.STREAM_DRAW sowie in WebGL 2 zusätzlich gl.STATIC_READ, gl.DYNAMIC_READ, gl.STREAM_READ, gl.STATIC_COPY, gl.DYNAMIC_COPY, gl.STREAM_COPY. |
|
| $srcOffset | GLuint | 0 | Nur mit ArrayBufferView: Index des ersten Elements, ab dem gelesen wird (in Elementen, nicht Bytes). |
| $length | GLuint | 0 | Nur mit ArrayBufferView: Anzahl der zu kopierenden Elemente. 0 bedeutet: bis zum Ende der Sicht. |
Rückgabewert
gl.getError() gemeldet.Beispiele
Vertex-Positionen eines Dreiecks hochladen
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl2');
const positions = new Float32Array([
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5,
]);
const vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
console.log(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE));
Index-Puffer für ein Rechteck aus zwei Dreiecken
const gl = document.querySelector('canvas').getContext('webgl2');
const vao = gl.createVertexArray();
gl.bindVertexArray(vao); // Index-Puffer-Bindung wird im VAO gespeichert
const indices = new Uint16Array([0, 1, 2, 2, 1, 3]);
const ibo = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
// später: gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
console.log(gl.getError() === gl.NO_ERROR);
Uniform-Buffer vorab reservieren und pro Frame aktualisieren
const gl = document.querySelector('canvas').getContext('webgl2');
// Platz für eine 4x4-Matrix (16 Floats = 64 Bytes)
const ubo = gl.createBuffer();
gl.bindBuffer(gl.UNIFORM_BUFFER, ubo);
gl.bufferData(gl.UNIFORM_BUFFER, 64, gl.DYNAMIC_DRAW);
gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, ubo);
const matrix = new Float32Array(16);
const render = (time) => {
matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1;
matrix[12] = Math.sin(time / 1000) * 0.5;
gl.bindBuffer(gl.UNIFORM_BUFFER, ubo);
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, matrix); // kein Neuanlegen
requestAnimationFrame(render);
};
requestAnimationFrame(render);
Nur einen Ausschnitt mit srcOffset und length hochladen
const gl = document.querySelector('canvas').getContext('webgl2');
// Großes Array mit mehreren Meshes; Mesh B beginnt bei Element 6
const allVertices = new Float32Array([
0, 0, 1, 0, 0, 1, // Mesh A (6 Floats)
0, 0, 1, 0, 1, 1, 0, 1 // Mesh B (8 Floats)
]);
const bufB = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufB);
gl.bufferData(gl.ARRAY_BUFFER, allVertices, gl.STATIC_DRAW, 6, 8);
console.log(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE));