Eric
Eric

Reputation: 148

three.js textureloader multiple images

So I have a website that does a few things in webgl w/ three.js, and I noticed that loadTexture is going away soon, and that I should probably switch to using textureloaders. Basically, i'd like to preload all my textures before any code executes at the start of my code. I was thinking about doing something like below, which will allow me to load any number of images, and assign them to a texture object that can be called when needed.

var loadedtex = {}
var to_load = ['images/a.png','images/b.png','images/c.png']
var texture_loader = new THREE.TextureLoader();
for(var i=0;i<to_load.length;i++){
    texture_loader.load(to_load[i],function(tex){
        loadedtex[to_load[i]] = tex
    })
}

I'm probably missing something obvious, but I can't quite get it to work correctly. When I use the code above, loadedtex will fill up loadedtex['images/c.png'] every time, instead of properly looping and remember which "i" value it should be using.

Proper result should be something like:

loadedtex['images/a.png'] = Three.Texture{}...
loadedtex['images/b.png'] = Three.Texture{}...
loadedtex['images/c.png'] = Three.Texture{}...

but what i really get is:

loadedtex['images/c.png'] = Three.Texture{}

I know its because the "i" variable will always be max value by the time anything loads, but i'm not sure how to accomplish what i want.

Thanks.

---edit---

This is what I ended up with. Seems to work well. Thanks for the advice.

var loadedtex = {}
var textureloaded = 0
var to_load = ['images/a.png','images/b.png','images/c.png']
var texture_loader = new THREE.TextureLoader();
load_textures = function(){
    if (textureloaded == to_load.length){return}
    var texture = to_load[textureloaded]
    texture_loader.load(texture,function(tex){
        loadedtex[texture] = tex
        textureloaded += 1
        load_textures()
    })  
}
load_textures()

Upvotes: 4

Views: 3250

Answers (2)

mika
mika

Reputation: 1451

If you're using ES6:

let assets = [ 
    { name:'img1', url:'img/img1.png' },
    { name:'img2', url:'img/img2.png' },
    { name:'img3', url:'img/img3.png' },
];
this.textures = {};
for ( let img of assets ) {
     this.loader.load(img.url, ( texture ) => {
        this.textures[img.name] = texture;
        assets.splice( assets.indexOf(img), 1);
        if ( !assets.length ) {
            this.init()
        }
        console.log('[TextureLoader] Loaded %o', img.name);
    });  
}

Upvotes: 2

Rohan Kumar
Rohan Kumar

Reputation: 40639

Try to make a closure function for it like,

for(var i=0;i<to_load.length;i++){
    (function(tl){
       texture_loader.load(tl,function(tex){
           loadedtex[tl] = tex
       })
    })(to_load[i]);
}

Upvotes: 0

Related Questions