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

WebGLRenderingContext.deleteFramebuffer()

Methode

Löscht ein <code>WebGLFramebuffer</code>-Objekt und gibt die zugehörigen GPU-Ressourcen frei.

seit JavaScript Baseline: alle Browser (WebGL 1) Kategorie: webapi

Signatur

WebGLRenderingContext.prototype.deleteFramebuffer(framebuffer)

Beschreibung

Mit deleteFramebuffer() markieren Sie ein Framebuffer-Objekt, das Sie zuvor mit createFramebuffer() angelegt haben, zum Löschen. Framebuffer werden für Offscreen-Rendering genutzt, etwa für Nachbearbeitungseffekte, Schattenkarten oder Picking. Brauchen Sie einen Framebuffer nicht mehr, sollten Sie ihn ausdrücklich löschen. So vermeiden Sie Speicherlecks auf der Grafikkarte.

Ist der Framebuffer beim Löschen gerade gebunden (gl.bindFramebuffer(gl.FRAMEBUFFER, fb)), wird die Bindung automatisch aufgehoben. Danach zeichnet der Kontext wieder in den Standard-Framebuffer, also in das Canvas.

Wichtig: Wenn Sie einen Framebuffer löschen, werden seine Anhänge nicht mitgelöscht. Texturen und Renderbuffer, die per framebufferTexture2D() oder framebufferRenderbuffer() angehängt sind, müssen Sie selbst mit deleteTexture() bzw. deleteRenderbuffer() freigeben.

Parameter

Name Typ Default Beschreibung
$framebuffer Pflicht WebGLFramebuffer | null Das Framebuffer-Objekt, das gelöscht werden soll. Bei null oder einem bereits gelöschten Objekt passiert nichts.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined).

Beispiele

Framebuffer anlegen und wieder löschen

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

const fb = gl.createFramebuffer();
console.log(gl.isFramebuffer(fb)); // noch false: nie gebunden

gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
console.log(gl.isFramebuffer(fb));

gl.deleteFramebuffer(fb);
console.log(gl.isFramebuffer(fb));
console.log(gl.getParameter(gl.FRAMEBUFFER_BINDING));
false true false null

Render-Target samt Anhängen sauber aufräumen

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

const createRenderTarget = (width, height) => {
  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);

  const depth = gl.createRenderbuffer();
  gl.bindRenderbuffer(gl.RENDERBUFFER, depth);
  gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);

  const framebuffer = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
    gl.TEXTURE_2D, texture, 0);
  gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
    gl.RENDERBUFFER, depth);
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);

  return { framebuffer, texture, depth };
};

const disposeRenderTarget = ({ framebuffer, texture, depth }) => {
  // Anhänge werden NICHT automatisch gelöscht
  gl.deleteFramebuffer(framebuffer);
  gl.deleteTexture(texture);
  gl.deleteRenderbuffer(depth);
};

const target = createRenderTarget(512, 512);
// ... Offscreen rendern ...
disposeRenderTarget(target);
console.log('Render-Target freigegeben');
Render-Target freigegeben

Neu anlegen bei Größenänderung des Canvas

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

const observer = new ResizeObserver(() => {
  // alten Framebuffer verwerfen und neuen erzeugen
  gl.deleteFramebuffer(pickingFb);
  pickingFb = gl.createFramebuffer();
  console.log('Picking-Framebuffer neu angelegt');
});
observer.observe(canvas);
Picking-Framebuffer neu angelegt

// Wichtig · Fallstricke

  • Anhänge bleiben bestehen: Texturen und Renderbuffer löschen Sie jeweils selbst. Andernfalls bleibt GPU-Speicher belegt.
  • Ist der gelöschte Framebuffer gebunden, fällt die Bindung auf null (das Canvas) zurück. Nachfolgende Zeichenbefehle landen dann unbemerkt auf dem Bildschirm.
  • Ein gelöschtes Objekt dürfen Sie nicht erneut binden. bindFramebuffer() mit einem gelöschten Framebuffer erzeugt den Fehler INVALID_OPERATION. Setzen Sie Ihre Referenz deshalb am besten auf null.
  • Ein Framebuffer aus einem anderen WebGL-Kontext erzeugt ebenfalls INVALID_OPERATION.
  • Nach einem Kontextverlust (webglcontextlost) sind ohnehin alle Objekte ungültig. Ein Aufruf richtet dann keinen Schaden an, bewirkt aber auch nichts.
  • Die Methode ist in allen modernen Browsern verfügbar und gibt es identisch auch in WebGL2RenderingContext.