Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reload libgdx unmanaged Texture after OpenGL context loss

Tags:

android

libgdx

I'm downloading images over the network and add them to my libgdx UI as Image actors using this:

Pixmap pm = new Pixmap(data, 0, data.length);
Texture t = new Texture(pm);
TextureRegion tr = new TextureRegion(t,200,300);
TextureRegionDrawable trd = new TextureRegionDrawable(tr);
Image icon = new Image();
icon.setDrawable(trd);

Given this I need some way of reloading the texture data since it is lost when the OpenGL context is lost (e.g. because the screen goes to sleep).

I've tried making my own manager class, adding

DynamicTextureManager.register(t, pm); // Register texture together with the source pixmap

to the above snippet, and in resume() I do:

DynamicTextureManager.reload();

The manager class:

public class DynamicTextureManager {
    private static LinkedHashMap<Texture, Pixmap> theMap = new
      LinkedHashMap<Texture,Pixmap>();
    public static void reload() {
        Set<Entry<Texture,Pixmap>> es = theMap.entrySet();
        for(Entry<Texture,Pixmap> e : es) {
            Texture t = e.getKey();
            Pixmap p = e.getValue();

            t.draw(p, 0, 0);
        }   
    }

    public static void register(Texture t, Pixmap p) {
        theMap.put(t, p);
    }
}

But this doesn't help - I still end up with the texture being unloaded and white areas instead of the image.

How should this be done? I haven't been able to find any code demonstrating this!

like image 233
johlo Avatar asked Nov 13 '22 11:11

johlo


1 Answers

Adding my solution as a reference. I now register the Image object and the Pixmap object with my manager, on reload() the Texture is re-created from the Pixmap and I set the new Texture for the old Image. Works for me, but more elegant solutions are welcome.

import java.util.Map.Entry;
public class DynamicTextureManager {
    private static final class MapData {
        Pixmap pixmap;
        int width;
        int height;
    }

    private static WeakHashMap<Image, MapData> theMap = new WeakHashMap<Image, MapData>();

    public static void reload() {
        Set<Entry<Image, MapData>> es = theMap.entrySet();
        for (Entry<Image, MapData> e : es) {
            Image i = e.getKey();
            MapData d = e.getValue();

            Texture t = new Texture(d.pixmap);
            TextureRegion tr;
            if(d.width == -1 || d.height == -1) {
                tr = new TextureRegion(t);
            }
            else {
                tr = new TextureRegion(t,d.width, d.height);                
            }
            TextureRegionDrawable trd = new TextureRegionDrawable(tr);
            i.setDrawable(trd);
        }
    }

    public static void register(Image i, Pixmap p) {
        MapData d = new MapData();
        d.pixmap = p;
        d.width = -1;
        d.height = -1;
        theMap.put(i, d);
    }

    public static void register(Image i, Pixmap p, int width, int height) {
        MapData d = new MapData();
        d.pixmap = p;
        d.width = width;
        d.height = height;

        theMap.put(i, d);
    }

}
like image 148
johlo Avatar answered Nov 15 '22 07:11

johlo