Reputation: 1066
I'm trying to add a canvas with context 2d
as a texture
to a webgl
canvas based on this example here. The texture appears to be blank on the webgl
canvas but the image is loaded when I append the texture canvas to theDOM
on it's own. What may I be missing here?
const canvas = document.createElement("canvas");
const textureCanvas = document.createElement('canvas');
textureCanvas.width = 200
textureCanvas.height = 200
const ctx = textureCanvas.getContext('2d')
const img = new Image();
img.src = "https://i.imgur.com/uIEexIc.jpg";
img.crossOrigin = 'Anonymous'
img.onload = (i) => {
ctx.drawImage(img, 0,0, 200, 200)
}
const gl = canvas.getContext("webgl");
const canvasTexture = gl.createTexture();
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.bindTexture(gl.TEXTURE_2D, canvasTexture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureCanvas);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
gl.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
Upvotes: 0
Views: 2470
Reputation: 2703
I've tried to investigate the problem.
It seems, that forcing the texture canvas to have dimensions as power of 2 fixes the texture visibility.
You can try to replace this block in your code:
img.onload = (i) => {
ctx.drawImage(img, 0,0, 200, 200)
}
to this block:
img.onload = (ev) => {
const w = getPowerOfTwo(img.width);
const h = getPowerOfTwo(img.height);
textureCanvas.width = w
textureCanvas.height = h
ctx.drawImage(img, 0, 0, w, h);
handleLoadedTexture(textureCanvas);
}
Here I force textureCanvas to have width and height to be power or 2. The function is here:
function getPowerOfTwo(value, pow) {
var pow = pow || 1;
while (pow < value) {
pow *= 2;
}
return pow;
}
Also notice the code handleLoadedTexture(textureCanvas);
. Here I redraw (update) the texture with new loaded image.
All other code you can test here: jsfiddle. To be sure, that texture is served from canvas, I've added 'Hello World'
text above the image (see handleLoadedTexture
).
Upvotes: 0
Reputation:
A canvas can not be used as a "live" texture.
In other words, when your code calls gl.texImage2D(....., textureCanvas)
what happens is the contents of the canvas at that moment in time is copied to the texture just once.
In your code above the flow is this
You need to wait for the image to be drawn into the canvas before you call gl.texImage2D
Upvotes: 2