How to get texture.image without using onLoad callback function

The two options I know for loading textures are:

const texture = textureLoader.load(url)
texture.image // undefined

Or

textureLoader.load(url, texture=>{
    texture.image // object
})

I’m doing an API/Library where I just ask for the texture object. But I need to get the image object somehow. The problem of the second option is that make difficult for users to use it. Is there a way or a method to get the object image using the option one?

You shouldn’t create a new loader each time you load a texture,The loader always immediatelly returns a texture object, but that doesn’t mean the image is loaded, so this is why your first one won’t have it loaded at this point.

The thing is that I’m passing texture to my “fancy-api”. So I need to get the image object somehow. So again, is there a way to get the image object using the option one?
Like:

const texture = textureLoader.load(url)
texture.onLoadImage(image=>{...})

Isn’t that code the same? You just need to consider the loading to be asynchronous, so if you want to access the image object you’ll need a callback, either on that specific load or after loading a bunch of textures.

The image dom object is available immediatelly too btw, since in your first example you commented with “undefined”.

1 Like

Not the same, here is the difference:

How the user must use my API.

const fancyApi = new MyCoolFakeFancyApi()
textureLoader.load(url1, texture=>{
    fancyApi.add(texture)
})
textureLoader.load(url2, texture=>{
    fancyApi.add(texture)
})

This is how I’d like to be used:

const fancyApi = new MyCoolFakeFancyApi()
const texture1 = textureLoader.load(url1)
fancyApi.add(texture1)
const texture2 = textureLoader.load(url2)
fancyApi.add(texture2)

I’d like to make the onLoad internally, rather than letting the user doing it.

You could use a loading manager for this, create a THREE.LoadingManager and pass it to your THREE.TextureLoader, on the manager you set the onLoad callback as described here, when the items are loaded you could fancyApi.add them in that callback.

Or you could adapt your api to accept urls and create/return the texture object. In anyway when you call load a texture with a img dom element is created and the url is set so you can’t add a callback afterwards, just abstract it a little, you can make it even more userfriendly.

Could you show a snippet. I don’t get how to combine TextureLoader with LoadingManager

const myLoadingManager = new THREE.LoadingManager;
const textureLoader = new THREE.TextureLoader(myLoadingManager);

But it might rather help if you could describe what your api is doing, like i said you might rather want to make the load call from your api instead.

I think I just found a solution, but don’t know the tradeoffs of this:

    const textureOnUpdate = texture.onUpdate
    texture.onUpdate = (...args) => {
        texture.image // it works
        if (typeof textureOnUpdate === 'function') {  // in case was defined already by the user
            textureOnUpdate(...args)
        }
        texture.onUpdate = textureOnUpdate
    }