package graphics;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.EXTTextureFilterAnisotropic.*;
import org.lwjgl.util.glu.MipMap;
import org.newdawn.slick.opengl.InternalTextureLoader;
import org.newdawn.slick.opengl.TextureImpl;
import org.newdawn.slick.util.ResourceLoader;
/**
* @author simokr
* @param <R> Slick TextureImpl
* @param <E> Integer
*/
public class TextureHandler<R extends TextureImpl, E extends Integer> extends ResourceHandler<R,E>{
private final float maxAF;
public TextureHandler() {
super();
maxAF = glGetFloat(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
this.addEmptyTexture();
}
@Override
protected E getExternal(String name) {
R resource = this.resources.get(name);
if(resource == null){
/* This texture has failed to load. Return the grey texture instead. */
return (E)new Integer(this.resources.get("empty").getTextureID());
}
return (E)new Integer(resource.getTextureID());
}
@Override
protected R load(String path) {
R tex;
try {
tex = (R)InternalTextureLoader.get().getTexture(ResourceLoader.getResourceAsStream(path), path, true, GL_LINEAR, null);
} catch (IOException ex) {
Logger.getLogger(TextureHandler.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
glBindTexture(GL_TEXTURE_2D, 0);
this.buildMipmaps(tex);
return tex;
}
private void buildMipmaps(R tex){
glBindTexture(GL_TEXTURE_2D, tex.getTextureID());
int width = (int)tex.getImageWidth();
int height = (int)tex.getImageHeight();
byte[] texbytes = tex.getTextureData();
int components = texbytes.length / (width*height);
ByteBuffer texdata = ByteBuffer.allocateDirect(texbytes.length);
texdata.put(texbytes);
texdata.rewind();
MipMap.gluBuild2DMipmaps(GL_TEXTURE_2D, components, width, height, components==3? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, texdata);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this.maxAF);
glBindTexture(GL_TEXTURE_2D, 0);
}
@Override
protected void freeIt(R resource) {
System.out.println("Releasing texture");
glDeleteTextures(resource.getTextureID());
System.out.println(resource.getTextureRef());
resource.release();
}
/**
* Adds a grey texture to textures.
*
* This is used when something requests an invalid texture with getTexture.
*/
private void addEmptyTexture(){
int width = 256, height = 256;
ByteBuffer buffer = ByteBuffer.allocateDirect(width*height*4);
for(int i = 0; i < (width*height*4); i++){
buffer.put((byte) ((i%4 == 3)?255:128));
}
buffer.flip();
R texImpl = (R)new TextureImpl("emptytexture", GL_TEXTURE_2D, 0);
texImpl.setTextureData(GL_RGBA, 4, GL_LINEAR, GL_LINEAR, buffer);
texImpl.setTextureFilter(GL_LINEAR);
texImpl.setTextureWidth(width);
texImpl.setTextureHeight(height);
texImpl.reload();
this.resources.put("empty", texImpl);
buffer.clear();
buffer = null;
}
}