texSubImage2D
is not the function you want. You're running into three problems:
texSubImage2D
does not copy a subset of image
into the GL texture. It copies the entirety of image
on top of the GL texture at a given offset.
texSubImage2D
can only modify existing texture data, and will mess up unless texImage2D
has been called first for the GL texture.
- The calling style you're using for
texSubImage2D
expects a pixel array instead of an HTMLImageElement
.
There are four possible signatures for these methods:
// These two accept the normal HTMLImageElement, etc. for the last param.
texImage2D(enum target, int level, enum internalformat, enum format,
enum type, Object object);
texSubImage2D(enum target, int level, int xoffset, int yoffset,
enum format, enum type, Object object);
// These two accept a Uint8Array[] of pixels as the last parameter, despite
// being documented as wanting an ImageData object. The only reason these
// have a width/height param is *because* they take a pixel array, and GL
// doesn't know how large the image is.
texImage2D(enum target, int level, enum internalformat, long width,
long height, int border, enum format, enum type, Object pixels);
texSubImage2D(enum target, int level, int xoffset, int yoffset,
long width, long height, enum format, enum type, Object pixels);
To create a texture using the first 32x32 pixels of your image, do something like this instead:
var spriteCanvas = document.createElement('canvas');
spriteCanvas.width = 32;
spriteCanvas.height = 32;
var spriteContext = spriteCanvas.getContext('2d');
spriteContext.drawImage(image, 0, 0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, spriteCanvas);