Signatur
Beschreibung
checkFramebufferStatus() prüft, ob der Framebuffer, der gerade an das angegebene Ziel gebunden ist, vollständig ist, also zum Rendern oder Auslesen benutzt werden kann. Dafür müssen die Anhänge (Texturen oder Renderbuffer) zueinander passen, zum Beispiel in Größe und Format.
Die Methode brauchst du vor allem beim Render-to-Texture, bei Post-Processing-Effekten, Shadow-Maps oder beim Offscreen-Rendering. Ruf sie am besten direkt nach dem Einrichten eines WebGLFramebuffer auf, also nach framebufferTexture2D() bzw. framebufferRenderbuffer(). So findest du Konfigurationsfehler früh und nicht erst, wenn Zeichenaufrufe ohne erkennbaren Grund scheitern.
Ist kein eigener Framebuffer gebunden (null, also der Standard-Framebuffer der Canvas), liefert die Methode immer gl.FRAMEBUFFER_COMPLETE. Ist der Framebuffer unvollständig, lösen Zeichen- und Lesebefehle wie drawArrays(), clear() oder readPixels() den Fehler INVALID_FRAMEBUFFER_OPERATION aus.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | GLenum | Das Bindungsziel. In WebGL 1 nur gl.FRAMEBUFFER. In WebGL 2 zusätzlich gl.DRAW_FRAMEBUFFER und gl.READ_FRAMEBUFFER (dabei entspricht gl.FRAMEBUFFER dem Ziel DRAW_FRAMEBUFFER). |
Rückgabewert
gl.FRAMEBUFFER_COMPLETE: Der Framebuffer ist einsatzbereit.gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT: Ein Anhang ist unvollständig oder ungültig.gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: Es gibt keinen Anhang.gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS: Die Anhänge sind unterschiedlich groß (nur WebGL 1).gl.FRAMEBUFFER_UNSUPPORTED: Diese Kombination von Formaten wird nicht unterstützt, oder Tiefen- und Stencil-Anhänge sind unzulässig kombiniert.gl.FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: Die Anhänge haben unterschiedlich viele Samples (nur WebGL 2).0: Es ist ein Fehler aufgetreten, etwa weiltargetungültig ist (INVALID_ENUM).
Beispiele
Render-to-Texture-Framebuffer anlegen und prüfen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
const width = 512, height = 512;
// Ziel-Textur anlegen
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
// Framebuffer anlegen und Textur anhängen
const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
console.log(status === gl.FRAMEBUFFER_COMPLETE ? 'Framebuffer bereit' : `Fehler: 0x${status.toString(16)}`);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
Status-Code in lesbaren Text übersetzen
const describeFramebufferStatus = (gl, status) => {
const names = {
[gl.FRAMEBUFFER_COMPLETE]: 'FRAMEBUFFER_COMPLETE',
[gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT]: 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT',
[gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT]: 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT',
[gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS]: 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS',
[gl.FRAMEBUFFER_UNSUPPORTED]: 'FRAMEBUFFER_UNSUPPORTED'
};
return names[status] ?? `Unbekannt (${status})`;
};
const gl = document.createElement('canvas').getContext('webgl');
const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
// Absichtlich keinen Anhang gesetzt
console.log(describeFramebufferStatus(gl, gl.checkFramebufferStatus(gl.FRAMEBUFFER)));
Float-Textur-Unterstützung testen (WebGL 2)
const canRenderToFloat = (gl) => {
// Ohne diese Erweiterung darf man nicht in Float-Texturen rendern
if (!gl.getExtension('EXT_color_buffer_float')) return false;
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA16F, 4, 4);
const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
const ok = gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;
// Aufräumen
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
gl.deleteFramebuffer(fbo);
gl.deleteTexture(tex);
return ok;
};
const gl2 = document.createElement('canvas').getContext('webgl2');
console.log('Float-Rendering möglich:', gl2 ? canRenderToFloat(gl2) : false);
// Wichtig · Fallstricke
- Performance: Der Aufruf kann eine GPU-Synchronisierung erzwingen. Ruf ihn deshalb nur einmal nach dem Einrichten bzw. Ändern des Framebuffers auf und nicht in jedem Frame der Render-Schleife.
- Die Methode prüft immer den aktuell gebundenen Framebuffer. Vergisst du
bindFramebuffer(), prüfst du den Standard-Framebuffer, und der meldet immerFRAMEBUFFER_COMPLETE. - Ob sich bestimmte Formate rendern lassen (z. B. Float- oder Half-Float-Texturen), hängt von Hardware und Erweiterungen ab, etwa
WEBGL_color_buffer_floatoderEXT_color_buffer_float. Ist das nicht möglich, liefert die Methode meistFRAMEBUFFER_UNSUPPORTED. - In WebGL 1 ist die Tiefen-Stencil-Kombination nur über
DEPTH_STENCIL_ATTACHMENTmitDEPTH_STENCIL-Renderbuffer zulässig. Getrennte Tiefen- und Stencil-Anhänge führen zuFRAMEBUFFER_UNSUPPORTED. - Geht der WebGL-Kontext verloren (
webglcontextlost), gibt die Methode0zurück. - Kompatibilität: In allen modernen Browsern verfügbar, auch in
WebGL2RenderingContextund in Workern überOffscreenCanvas.