WebGL - 是否可以将 gl 传递给 img.onload 函数?
WebGL - Is it possible to pass gl into an img.onload function?
在我用 ES6 编写的 WebGL 程序中,我有一个名为 Texture 的 class。
首先,它将纹理绘制为 1 个红色像素。加载图像后,我想用图像替换红色像素。
我有点卡住了,因为我不确定最好的方法是什么,因为它目前会抛出错误并且不起作用:
Uncaught TypeError: Failed to execute 'texImage2D' on 'WebGLRenderingContext': No function was found that matched the signature provided.
我最好的猜测是发生这种情况是因为 JavaScript 是异步的,所以一旦图像加载,gl 就消失了,或者我可能错了。
帮助理解这个and/or一个解决方案将不胜感激。
export default class Texture {
constructor(gl, src) {
// create texture then bind it
this.texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
// texture settings for the texture
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
// create it as a red pixel first so it can be quickly drawn then replaced with the actual image
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 0, 0, 255]));
// active the texture
gl.activeTexture(gl.TEXTURE0);
// load the image
this.img = new Image();
this.img.src = src;
// replace the red pixel with the texture once it is loaded
this.img.onload = function() {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.img);
}
}
}
我试过这个:
this.img.onload = function(gl) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.img);
}
但是它抛出这个错误:
Uncaught TypeError: t.texImage2D is not a function
您正在函数内部创建一个新范围。在 ES6 中防止它的最简单方法是箭头函数:
this.img.onload = () => {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.img);
}
onload
函数中的关键字 this
与您期望的 this
上下文不同。一种方法是使用 Sebastian Speitel 的答案中的箭头函数。
您还可以将引用保存到 self
变量中,这是一种常见的模式:
var self = this;
this.img.onload = function() {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self.img);
}
任何函数都可以从外部范围访问变量,这就是为什么 self
可以在 this.img.onload
.
内部访问的原因
在我用 ES6 编写的 WebGL 程序中,我有一个名为 Texture 的 class。
首先,它将纹理绘制为 1 个红色像素。加载图像后,我想用图像替换红色像素。
我有点卡住了,因为我不确定最好的方法是什么,因为它目前会抛出错误并且不起作用:
Uncaught TypeError: Failed to execute 'texImage2D' on 'WebGLRenderingContext': No function was found that matched the signature provided.
我最好的猜测是发生这种情况是因为 JavaScript 是异步的,所以一旦图像加载,gl 就消失了,或者我可能错了。
帮助理解这个and/or一个解决方案将不胜感激。
export default class Texture {
constructor(gl, src) {
// create texture then bind it
this.texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
// texture settings for the texture
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
// create it as a red pixel first so it can be quickly drawn then replaced with the actual image
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 0, 0, 255]));
// active the texture
gl.activeTexture(gl.TEXTURE0);
// load the image
this.img = new Image();
this.img.src = src;
// replace the red pixel with the texture once it is loaded
this.img.onload = function() {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.img);
}
}
}
我试过这个:
this.img.onload = function(gl) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.img);
}
但是它抛出这个错误:
Uncaught TypeError: t.texImage2D is not a function
您正在函数内部创建一个新范围。在 ES6 中防止它的最简单方法是箭头函数:
this.img.onload = () => {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.img);
}
onload
函数中的关键字 this
与您期望的 this
上下文不同。一种方法是使用 Sebastian Speitel 的答案中的箭头函数。
您还可以将引用保存到 self
变量中,这是一种常见的模式:
var self = this;
this.img.onload = function() {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self.img);
}
任何函数都可以从外部范围访问变量,这就是为什么 self
可以在 this.img.onload
.