package net.sf.openrocket.gui.figure3d;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLProfile;
import net.sf.openrocket.appearance.Decal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureData;
import com.jogamp.opengl.util.texture.TextureIO;
public class TextureCache {
private static final Logger log = LoggerFactory.getLogger(TextureCache.class);
private Map<String, Texture> oldTexCache = null;
private Map<String, Texture> texCache = null;
public void init(GLAutoDrawable drawable) {
if (texCache != null)
throw new IllegalStateException(this + " already initialized.");
oldTexCache = new HashMap<String, Texture>();
texCache = new HashMap<String, Texture>();
}
public void dispose(GLAutoDrawable drawable) {
if (texCache == null)
throw new IllegalStateException(this + " not initialized.");
flushTextureCache(drawable);
oldTexCache = null;
texCache = null;
}
public void flushTextureCache(GLAutoDrawable drawable) {
advanceCacheGeneration(drawable);
advanceCacheGeneration(drawable);
}
public void advanceCacheGeneration(GLAutoDrawable drawable) {
if (texCache == null)
throw new IllegalStateException(this + " not initialized.");
log.debug("ClearCaches");
for (Map.Entry<String, Texture> e : oldTexCache.entrySet()) {
log.debug("Destroying Texture for " + e.getKey());
if (e.getValue() != null)
e.getValue().destroy(drawable.getGL().getGL2());
}
oldTexCache = texCache;
texCache = new HashMap<String, Texture>();
}
public Texture getTexture(URL uri) {
if (texCache == null)
throw new IllegalStateException(this + " not initialized.");
if (uri == null)
return null;
String imageName = uri.toString();
// Return the Cached value if available
if (texCache.containsKey(imageName))
return texCache.get(imageName);
// If the texture is in the Old Cache, save it.
if (oldTexCache.containsKey(imageName)) {
texCache.put(imageName, oldTexCache.get(imageName));
oldTexCache.remove(imageName);
return texCache.get(imageName);
}
// Otherwise load it.
Texture tex = null;
try {
log.debug("Loading texture " + uri);
InputStream is = uri.openStream();
TextureData data = TextureIO.newTextureData(GLProfile.getDefault(), is, GL.GL_RGBA, GL.GL_RGBA, true, null);
tex = TextureIO.newTexture(data);
} catch (Throwable e) {
log.error("Error loading Texture", e);
}
texCache.put(imageName, tex);
return tex;
}
public Texture getTexture(Decal decal) {
if (texCache == null)
throw new IllegalStateException(this + " not initialized.");
if (decal == null)
return null;
String imageName = decal.getImage().getName();
// Return the Cached value if available
if (texCache.containsKey(imageName))
return texCache.get(imageName);
// If the texture is in the Old Cache, save it.
if (oldTexCache.containsKey(imageName)) {
texCache.put(imageName, oldTexCache.get(imageName));
oldTexCache.remove(imageName);
return texCache.get(imageName);
}
// Otherwise load it.
Texture tex = null;
try {
log.debug("Loading texture " + decal);
InputStream is = decal.getImage().getBytes();
TextureData data = TextureIO.newTextureData(GLProfile.getDefault(), is, GL.GL_RGBA, GL.GL_RGBA, true, null);
tex = TextureIO.newTexture(data);
} catch (Throwable e) {
log.error("Error loading Texture", e);
}
texCache.put(imageName, tex);
return tex;
}
}