ArthurN
ArthurN

Reputation: 179

Using array of images as texture in WebGL

How to use an array of textures (which contain different images) in WebGL without initializing each texture separately? I want to display a cube and a pyramid (organized as an array), each with a different texture image. Here is a part of the code (to initialize the textures):

function handleTexture(texture) {
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.Img);
    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);
}

function initTextures() {
    for (i=0; i<2; i++) {
        tex[i] = gl.createTexture();
        tex[i].Img = new Image();
        tex[i].Img.onload = function() { handleTexture(tex[i]); }
        tex[i].Img.src = texImgs[i];   // The name of the image file
    }
}

The cube and pyramid are displayed in black color (no texture), and I get this error in the page:

Uncaught TypeError: Cannot read property 'Img' of undefined  // gl.texImage2D()
tex.(anonymous function).Img.onload                          // tex[i].Img.onload = ...

I don't have this error if I initialize the texture separately, not using an array, but tex1 and tex2. Any suggestion on how to do this using array?

Upvotes: 1

Views: 1211

Answers (1)

Dragan Okanovic
Dragan Okanovic

Reputation: 7761

When you do:

tex[i] = gl.createTexture();

tex[i] becomes a type of WebGLTexture and you cannot attach new properties on that object as you did with .Img property. So slightly more correct version would be:

var tex = [], texImgs = ['pyra.jpg', 'cube.jpg'];

function handleTexture(myTexture) {
    myTexture.texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, myTexture.texture);

    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, myTexture.image);
    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);
}

function initTextures() {
    for (var i=0; i<2; i++) {
        (function(index) {
            tex[index] = new Object();
            tex[index].texture = null;
            tex[index].image = new Image();
            tex[index].image.onload = function() { handleTexture(tex[index]); }
            tex[index].image.src = texImgs[index];   // The name of the image file
        })(i);
    }
}

Note that you create an object that has image and texture property separated.

Hope this helps you.

EDIT:

Closure messes the index of the tex.

Upvotes: 1

Related Questions