Yes, I know about Spritesheets and their complications.
I think my solution may be to use rcTex coordinates for the subset of the spritesheet texture, place the full texture on an offscreen canvas and use that canvas as the 'data' for UpdateTexture.
Here's an example. I will do a couple of changes:
- gl.readPixels needs to read from the rectangle subset based on rcTex subset of the spritesheet
- UpdateTexture() can use a Canvas directly, so we don't need to create the img from it, can return the canvas instead.
function createImageFromTexture(gl, texture, width, height) {
// Create a framebuffer backed by the texture
var framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
// Read the contents of the framebuffer
var data = new Uint8Array(width * height * 4);
gl.readPixels(<change based on rcTex and texture width to get lower x>, <change based on rcTex and texture height to get get lower y>, <change based on rcTex width and texel width>, <change based on rcTex height and texel height>, gl.RGBA, gl.UNSIGNED_BYTE, data);
gl.deleteFramebuffer(framebuffer);
// Create a 2D canvas to store the result
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var context = canvas.getContext('2d');
// Copy the pixels to a 2D canvas
var imageData = context.createImageData(width, height);
imageData.data.set(data);
context.putImageData(imageData, 0, 0);
var img = new Image();
img.src = canvas.toDataURL();
return img;
}