Signatur
Beschreibung
deleteShader() gibt ein Shader-Objekt frei, das vorher mit createShader() erzeugt wurde. Der Shader wird dabei zur Löschung markiert. Ist er noch an ein oder mehrere WebGLProgram-Objekte angehängt (attachShader()), wird er erst dann tatsächlich gelöscht, wenn er von allen Programmen gelöst wurde (detachShader()) oder diese Programme selbst gelöscht werden.
Üblicherweise geht man so vor: Shader kompilieren, an ein Programm anhängen, Programm mit linkProgram() linken und danach die Shader lösen und löschen. Das gelinkte Programm enthält den ausführbaren Code bereits, die einzelnen Shader-Objekte braucht man danach nicht mehr. So sammeln sich in langlebigen Anwendungen oder beim erneuten Laden von Shadern (Hot-Reload) keine ungenutzten Objekte an.
Auch wenn das Kompilieren fehlschlägt, sollte man den Shader nach dem Auslesen des Fehlerprotokolls mit getShaderInfoLog() löschen. Ob ein Shader zur Löschung markiert ist, lässt sich mit gl.getShaderParameter(shader, gl.DELETE_STATUS) abfragen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $shader Pflicht | WebGLShader | null | Das zu löschende Shader-Objekt aus gl.createShader(). Bei null oder einem bereits gelöschten Shader passiert nichts. |
Rückgabewert
undefined).Beispiele
Shader nach dem Linken aufräumen
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
const compile = (type, source) => {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
return shader;
};
const vs = compile(gl.VERTEX_SHADER, `
attribute vec4 aPos;
void main() { gl_Position = aPos; }`);
const fs = compile(gl.FRAGMENT_SHADER, `
precision mediump float;
void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }`);
const program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
// Shader werden nach dem Linken nicht mehr benötigt
gl.detachShader(program, vs);
gl.detachShader(program, fs);
gl.deleteShader(vs);
gl.deleteShader(fs);
console.log(gl.getProgramParameter(program, gl.LINK_STATUS));
Fehlgeschlagene Kompilierung sauber behandeln
const gl = document.createElement('canvas').getContext('webgl');
const createShader = (type, source) => {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const log = gl.getShaderInfoLog(shader);
gl.deleteShader(shader); // Speicher trotz Fehler freigeben
throw new Error(`Shader-Fehler: ${log}`);
}
return shader;
};
try {
createShader(gl.FRAGMENT_SHADER, 'void main() { gl_FragColor = vec4(1.0) }');
} catch (err) {
console.error(err.message);
}
Verzögerte Löschung über DELETE_STATUS prüfen
const gl = document.createElement('canvas').getContext('webgl');
const shader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(shader, 'void main() { gl_Position = vec4(0.0); }');
gl.compileShader(shader);
const program = gl.createProgram();
gl.attachShader(program, shader);
gl.deleteShader(shader);
// Noch angehängt: nur markiert, nicht wirklich gelöscht
console.log(gl.getShaderParameter(shader, gl.DELETE_STATUS));
gl.detachShader(program, shader); // erst jetzt tatsächlich freigegeben
console.log(gl.isShader(shader));
// Wichtig · Fallstricke
- Verzögerte Löschung: Solange der Shader an ein Programm angehängt ist, wird er nur markiert. Wer Speicher wirklich freigeben will, muss ihn zusätzlich mit
detachShader()lösen oder das Programm mitdeleteProgram()löschen. - Ein gelöschter Shader darf nicht mehr benutzt werden: Aufrufe wie
shaderSource()oderattachShader()mit einem gelöschten Shader erzeugen den FehlerINVALID_VALUE(abfragbar übergl.getError()). - Wird ein Shader übergeben, der zu einem anderen WebGL-Kontext gehört, entsteht ein
INVALID_OPERATION-Fehler. - Einige Entwicklertools und Treiber zeigen den Quelltext gelöschter Shader nicht mehr an. Für die Fehlersuche kann es daher sinnvoll sein, das Löschen im Entwicklungsmodus vorübergehend abzuschalten.
- Geht der Kontext verloren (
webglcontextlost), werden alle Objekte automatisch ungültig.deleteShader()ist dann nicht nötig. - In allen Browsern mit WebGL-Unterstützung verfügbar, ebenso in
WebGL2RenderingContext.