This commit is contained in:
syuilo 2025-06-02 19:46:18 +09:00
parent 74dbee9e15
commit 6adc9c910a
3 changed files with 29 additions and 23 deletions

View File

@ -147,7 +147,7 @@ const sampleImage_2_3_loading = new Promise<void>(resolve => {
const sampleImageType = ref(props.image != null ? 'provided' : '3_2'); const sampleImageType = ref(props.image != null ? 'provided' : '3_2');
watch(sampleImageType, async () => { watch(sampleImageType, async () => {
if (renderer != null) { if (renderer != null) {
renderer.destroy(); renderer.destroy(false);
renderer = null; renderer = null;
initRenderer(); initRenderer();
} }

View File

@ -131,7 +131,7 @@ export class ImageEffector {
void main() { void main() {
out_color = texture(u_texture, in_uv); out_color = texture(u_texture, in_uv);
} }
`)!; `);
this.renderInvertedTextureProgram = this.initShaderProgram(`#version 300 es this.renderInvertedTextureProgram = this.initShaderProgram(`#version 300 es
in vec2 position; in vec2 position;
@ -152,45 +152,43 @@ export class ImageEffector {
void main() { void main() {
out_color = texture(u_texture, in_uv); out_color = texture(u_texture, in_uv);
} }
`)!; `);
} }
public loadShader(type, source) { public loadShader(type: GLenum, source: string): WebGLShader {
const gl = this.gl; const gl = this.gl;
const shader = gl.createShader(type)!; const shader = gl.createShader(type);
if (shader == null) {
throw new Error('falied to create shader');
}
gl.shaderSource(shader, source); gl.shaderSource(shader, source);
gl.compileShader(shader); gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert( console.error(`falied to compile shader: ${gl.getShaderInfoLog(shader)}`);
`falied to compile shader: ${gl.getShaderInfoLog(shader)}`,
);
gl.deleteShader(shader); gl.deleteShader(shader);
return null; throw new Error(`falied to compile shader: ${gl.getShaderInfoLog(shader)}`);
} }
return shader; return shader;
} }
public initShaderProgram(vsSource, fsSource): WebGLProgram { public initShaderProgram(vsSource: string, fsSource: string): WebGLProgram {
const gl = this.gl; const gl = this.gl;
const vertexShader = this.loadShader(gl.VERTEX_SHADER, vsSource)!; const vertexShader = this.loadShader(gl.VERTEX_SHADER, vsSource);
const fragmentShader = this.loadShader(gl.FRAGMENT_SHADER, fsSource)!; const fragmentShader = this.loadShader(gl.FRAGMENT_SHADER, fsSource);
const shaderProgram = gl.createProgram();
const shaderProgram = gl.createProgram()!;
gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader); gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram); gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert( console.error(`failed to init shader: ${gl.getProgramInfoLog(shaderProgram)}`);
`failed to init shader: ${gl.getProgramInfoLog(
shaderProgram,
)}`,
);
throw new Error('failed to init shader'); throw new Error('failed to init shader');
} }
@ -363,7 +361,10 @@ export class ImageEffector {
return v.type === 'text' ? `text:${v.text}` : v.type === 'url' ? `url:${v.url}` : ''; return v.type === 'text' ? `text:${v.text}` : v.type === 'url' ? `url:${v.url}` : '';
} }
public destroy() { /*
* disposeCanvas = true loseContextを呼ぶためcanvasも再利用不可になるので注意
*/
public destroy(disposeCanvas = true) {
for (const shader of this.shaderCache.values()) { for (const shader of this.shaderCache.values()) {
this.gl.deleteProgram(shader); this.gl.deleteProgram(shader);
} }
@ -388,10 +389,12 @@ export class ImageEffector {
this.gl.deleteProgram(this.renderInvertedTextureProgram); this.gl.deleteProgram(this.renderInvertedTextureProgram);
this.gl.deleteTexture(this.originalImageTexture); this.gl.deleteTexture(this.originalImageTexture);
if (disposeCanvas) {
const loseContextExt = this.gl.getExtension('WEBGL_lose_context'); const loseContextExt = this.gl.getExtension('WEBGL_lose_context');
if (loseContextExt) loseContextExt.loseContext(); if (loseContextExt) loseContextExt.loseContext();
} }
} }
}
function createTexture(gl: WebGL2RenderingContext): WebGLTexture { function createTexture(gl: WebGL2RenderingContext): WebGLTexture {
const texture = gl.createTexture(); const texture = gl.createTexture();

View File

@ -98,7 +98,10 @@ export class WatermarkRenderer {
this.effector.render(); this.effector.render();
} }
public destroy(): void { /*
this.effector.destroy(); * disposeCanvas = true loseContextを呼ぶためcanvasも再利用不可になるので注意
*/
public destroy(disposeCanvas = true): void {
this.effector.destroy(disposeCanvas);
} }
} }