Signatur
Beschreibung
bufferData() reserviert GPU-Speicher für das Pufferobjekt, das gerade an den angegebenen Bindungspunkt (gl.ARRAY_BUFFER oder gl.ELEMENT_ARRAY_BUFFER) gebunden ist, und kopiert optional Daten hinein. Ein vorhandener Datenspeicher dieses Puffers wird dabei vollständig ersetzt, alte Inhalte gehen verloren.
Typischerweise lädt man damit Vertex-Daten (Positionen, Normalen, Texturkoordinaten, Farben) oder Indizes auf die GPU. Die Methode arbeitet immer auf dem Puffer, der vorher mit gl.bindBuffer() gebunden wurde, und nicht auf einem Pufferobjekt, das man ihr direkt übergibt.
Man kann entweder eine Größe in Bytes übergeben (der Speicher wird dann mit Nullen initialisiert) oder direkt ein ArrayBuffer, TypedArray bzw. eine DataView. Sollen die Daten später nur in Teilen aktualisiert werden, legt man den Speicher einmal mit bufferData() an und aktualisiert ihn danach mit bufferSubData(). Das ist meist schneller als jedes Mal neu zu allozieren.
Der Parameter usage ist ein Hinweis an den Treiber, wie oft die Daten geändert und gelesen werden. Er verändert nicht das Verhalten, kann aber die Leistung stark beeinflussen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | GLenum | Bindungspunkt: gl.ARRAY_BUFFER (Vertex-Attribute) oder gl.ELEMENT_ARRAY_BUFFER (Indizes). In WebGL 2 kommen weitere hinzu, z. B. gl.UNIFORM_BUFFER, gl.COPY_READ_BUFFER oder gl.PIXEL_PACK_BUFFER. |
|
| $sizeOrData Pflicht | GLsizeiptr | ArrayBuffer | SharedArrayBuffer | TypedArray | DataView | null | Entweder die Größe des Speichers in Bytes (Inhalt mit Nullen initialisiert) oder die Quelldaten, die in den Puffer kopiert werden. Bei null wird in WebGL 1 der Fehler INVALID_VALUE erzeugt. |
|
| $usage Pflicht | GLenum | Nutzungshinweis: gl.STATIC_DRAW (einmal setzen, oft zeichnen), gl.DYNAMIC_DRAW (häufig ändern, oft zeichnen), gl.STREAM_DRAW (einmal setzen, selten zeichnen). WebGL 2 ergänzt *_READ- und *_COPY-Varianten. |
|
| $srcOffset | GLuint | 0 | Nur WebGL 2 mit TypedArray-Quelle: Startindex in Elementen (nicht in Bytes), ab dem gelesen wird. |
| $length | GLuint | 0 | Nur WebGL 2: Anzahl der zu kopierenden Elemente. 0 bedeutet: bis zum Ende des Arrays. |
Rückgabewert
undefined). Fehler werden über gl.getError() gemeldet.Beispiele
Dreieck-Positionen in einen Vertex-Puffer laden
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
// Drei Eckpunkte (x, y) in Clip-Koordinaten
const positions = new Float32Array([
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5
]);
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
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('webgl');
const indices = new Uint16Array([0, 1, 2, 2, 1, 3]);
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
// Später beim Zeichnen (Programm und Attribute vorausgesetzt):
// gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
console.log(gl.getError() === gl.NO_ERROR);
Speicher vorab reservieren und pro Frame teilweise aktualisieren
const gl = document.querySelector('canvas').getContext('webgl');
const MAX_PARTICLES = 1000;
const FLOATS_PER_PARTICLE = 2;
const particleBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, particleBuffer);
// Nur Größe in Bytes angeben -> Speicher wird mit Nullen gefüllt
gl.bufferData(
gl.ARRAY_BUFFER,
MAX_PARTICLES * FLOATS_PER_PARTICLE * Float32Array.BYTES_PER_ELEMENT,
gl.DYNAMIC_DRAW
);
const data = new Float32Array(MAX_PARTICLES * FLOATS_PER_PARTICLE);
const update = (time) => {
for (let i = 0; i < MAX_PARTICLES; i++) {
data[i * 2] = Math.cos(time / 1000 + i) * 0.8;
data[i * 2 + 1] = Math.sin(time / 1000 + i) * 0.8;
}
gl.bindBuffer(gl.ARRAY_BUFFER, particleBuffer);
// Kein Neuanlegen, nur Inhalt überschreiben
gl.bufferSubData(gl.ARRAY_BUFFER, 0, data);
requestAnimationFrame(update);
};
requestAnimationFrame(update);
WebGL 2: nur einen Ausschnitt eines Arrays hochladen
const gl = document.querySelector('canvas').getContext('webgl2');
const all = new Float32Array([9, 9, 1, 2, 3, 4, 9, 9]);
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
// Ab Element 2, genau 4 Elemente -> [1, 2, 3, 4]
gl.bufferData(gl.ARRAY_BUFFER, all, gl.STATIC_DRAW, 2, 4);
console.log(gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE));