package net.fourbytes.shadow; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture.TextureFilter; import com.badlogic.gdx.graphics.g2d.PixmapPacker; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.ui.Image; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.BufferUtils; import com.badlogic.gdx.utils.ObjectMap; import net.fourbytes.shadow.mod.AMod; import net.fourbytes.shadow.utils.Garbage; import net.fourbytes.shadow.utils.MultiObject; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.URL; import java.nio.IntBuffer; public final class Images { private Images() {} private final static ObjectMap<String, Image> images = new ObjectMap<String, Image>(); private final static ObjectMap<String, TextureRegion> textureregs = new ObjectMap<String, TextureRegion>(); public static PixmapPacker packer; public static TextureAtlas atlas; public static Array<String> atlasList = new Array<String>(); public static void addImage(String savename, Image i) { images.put(savename, i); } public static Image getImage(String savename) { Image image = images.get(savename); if (image == null) { autoaddImage(savename); image = images.get(savename); } return image; } public static void addTextureRegion(String savename, TextureRegion reg) { textureregs.put(savename, reg); } public static TextureRegion getTextureRegion(String savename) { TextureRegion texturereg = textureregs.get(savename); if (texturereg == null) { autoaddImage(savename); texturereg = textureregs.get(savename); } return texturereg; } /** * Loads minimum of / only needed resources required for loading screen. */ public static void loadBasic() { //ETC / UI addImage("white", "data/white.png"); addImage("logo", "data/logo.png"); addImage("logo_4f", "data/logo_4f.png"); } public static void loadImages() { //ETC / UI addImage("light", "data/light.png"); addImage("cloud", "data/cloud.png"); addImage("cloud2", "data/cloud2.png"); addImage("cloud3", "data/cloud3.png"); addImage("moon", "data/moon.png"); addImage("void", "data/void.png"); //BLOCKS //... get added dynamically. //ENTITIES addImage("player", "data/player.png"); } public static void autoaddImage(String name) { String loadname = name; if (name.startsWith("block_")) { loadname = name.substring(6); loadname = "data/levels/tiles/" + loadname; } else { loadname = "data/" + loadname; } if (Gdx.files.internal(loadname+".png").exists()) { addImage(name, loadname+".png"); } else if (Gdx.files.internal(loadname+"block.png").exists()) { addImage(name, loadname+"block.png"); } } public static void addImage(String savename, String loadname) { try { Pixmap pm = new Pixmap(Gdx.files.internal(loadname)); packPixmap(pm, savename); } catch (Throwable t) { System.err.println("Loading failed: SN: "+savename+"; LN: "+loadname); t.printStackTrace(); } } public static void addImageByMod(AMod mod, String savename, String loadname) { try { URL url = mod.getClass().getResource("/assets/"+loadname); InputStream in = new BufferedInputStream(url.openStream()); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buf = new byte[2048]; int n; while (-1 != (n = in.read(buf))) { out.write(buf, 0, n); } out.close(); in.close(); byte[] response = out.toByteArray(); Pixmap pixmap = new Pixmap(response, 0, response.length); packPixmap(pixmap, savename); } catch (Throwable t) { System.err.println("Loading failed (from mod): SN: "+savename); t.printStackTrace(); } } private static void packPixmap(final Pixmap pm, final String savename) { if (Thread.currentThread() != Shadow.thread) { final boolean[] done = {false}; Gdx.app.postRunnable(new Runnable() { public void run() { packPixmap(pm, savename); done[0] = true; } }); while (!done[0]) { /*try { Thread.sleep(10L); } catch (InterruptedException e) { e.printStackTrace(); }*/ Thread.yield(); } return; } if (packer == null) { packer = new PixmapPacker(1024, 1024, Format.RGBA8888, 2, true); atlas = packer.generateTextureAtlas(TextureFilter.MipMapNearestNearest, TextureFilter.Nearest, true); } packer.pack(savename, pm); packer.updateTextureAtlas(atlas, TextureFilter.MipMapNearestNearest, TextureFilter.Nearest, true); TextureRegion region = atlas.findRegion(savename); //region = new TextureRegion((Texture)atlas.getTextures().toArray()[0], 0f, 0f, 1f, 1f); addTextureRegion(savename, region); Image i = new Image(region); addImage(savename, i); atlasList.add(savename); pm.dispose(); } /** * Splits an texture region into... umm... guess it. */ public static TextureRegion[][] split(String savename, int w, int h) { return split(getTextureRegion(savename), w, h); } private static ObjectMap<MultiObject, TextureRegion[][]> splitCache = new ObjectMap<MultiObject, TextureRegion[][]>(); /** * Splits an texture region into... umm... guess it. */ public static TextureRegion[][] split(TextureRegion reg, int w, int h) { MultiObject tmptrimo = Garbage.multiobjs.getNext(); tmptrimo.set(reg, w, h); TextureRegion[][] got = splitCache.get(tmptrimo); if (got != null) { return got; } w = Math.max(Math.max(w, -w), 1); h = Math.max(Math.max(h, -h), 1); Texture tex = reg.getTexture(); int subregw = reg.getRegionWidth()/w; int subregh = reg.getRegionHeight()/h; subregw = Math.max(subregw, -subregw); subregh = Math.max(subregh, -subregh); TextureRegion[][] regs = new TextureRegion[subregh][]; int xx = 0; int yy = 0; for (int y = reg.getRegionY(); y < reg.getRegionY() + reg.getRegionHeight(); y += h) { regs[yy] = new TextureRegion[subregw]; for (int x = reg.getRegionX(); x < reg.getRegionX() + reg.getRegionWidth(); x += w) { TextureRegion subreg = new TextureRegion(tex, x, y, w, h); regs[yy][xx] = subreg; xx++; if (xx >= regs[yy].length) { break; } } xx = 0; yy++; if (yy >= regs.length) { break; } } MultiObject mo = new MultiObject(reg, w, h); splitCache.put(mo, regs); return regs; } }