mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-11 22:31:52 +09:00
added sources for Slick
Former-commit-id: 1647fa32ef6894bd7db44f741f07c2f4dcdf9054 Former-commit-id: 0e5810dcfbe1fd59b13e7cabe9f1e93c5542da2d
This commit is contained in:
@@ -0,0 +1,530 @@
|
||||
package org.newdawn.slick.opengl;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.newdawn.slick.opengl.renderer.Renderer;
|
||||
import org.newdawn.slick.opengl.renderer.SGL;
|
||||
import org.newdawn.slick.util.ResourceLoader;
|
||||
|
||||
/**
|
||||
* A texture loaded based on many old versions that will load image data from a file
|
||||
* and produce OpenGL textures.
|
||||
*
|
||||
* @see ImageData
|
||||
*
|
||||
* @author kevin
|
||||
*/
|
||||
public class InternalTextureLoader {
|
||||
/** The renderer to use for all GL operations */
|
||||
protected static SGL GL = Renderer.get();
|
||||
/** The standard texture loaded used everywhere */
|
||||
private static final InternalTextureLoader loader = new InternalTextureLoader();
|
||||
|
||||
/**
|
||||
* Get the single instance of this texture loader
|
||||
*
|
||||
* @return The single instance of the texture loader
|
||||
*/
|
||||
public static InternalTextureLoader get() {
|
||||
return loader;
|
||||
}
|
||||
|
||||
/** The table of textures that have been loaded in this loader */
|
||||
private HashMap texturesLinear = new HashMap();
|
||||
/** The table of textures that have been loaded in this loader */
|
||||
private HashMap texturesNearest = new HashMap();
|
||||
/** The destination pixel format */
|
||||
private int dstPixelFormat = SGL.GL_RGBA8;
|
||||
/** True if we're using deferred loading */
|
||||
private boolean deferred;
|
||||
/** True if we should hold texture data */
|
||||
private boolean holdTextureData;
|
||||
|
||||
/**
|
||||
* Create a new texture loader based on the game panel
|
||||
*/
|
||||
private InternalTextureLoader() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate where texture data should be held for reinitialising at a future
|
||||
* point.
|
||||
*
|
||||
* @param holdTextureData True if we should hold texture data
|
||||
*/
|
||||
public void setHoldTextureData(boolean holdTextureData) {
|
||||
this.holdTextureData = holdTextureData;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if we should only record the request to load in the intention
|
||||
* of loading the texture later
|
||||
*
|
||||
* @param deferred True if the we should load a token
|
||||
*/
|
||||
public void setDeferredLoading(boolean deferred) {
|
||||
this.deferred = deferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we're using deferred loading
|
||||
*
|
||||
* @return True if we're loading deferred textures
|
||||
*/
|
||||
public boolean isDeferredLoading() {
|
||||
return deferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a particular named image from the cache
|
||||
*
|
||||
* @param name The name of the image to be cleared
|
||||
*/
|
||||
public void clear(String name) {
|
||||
texturesLinear.remove(name);
|
||||
texturesNearest.remove(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out the cached textures
|
||||
*/
|
||||
public void clear() {
|
||||
texturesLinear.clear();
|
||||
texturesNearest.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the loader to produce 16 bit textures
|
||||
*/
|
||||
public void set16BitMode() {
|
||||
dstPixelFormat = SGL.GL_RGBA16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new texture ID
|
||||
*
|
||||
* @return A new texture ID
|
||||
*/
|
||||
public static int createTextureID()
|
||||
{
|
||||
IntBuffer tmp = createIntBuffer(1);
|
||||
GL.glGenTextures(tmp);
|
||||
return tmp.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a texture from a specific file
|
||||
*
|
||||
* @param source The file to load the texture from
|
||||
* @param flipped True if we should flip the texture on the y axis while loading
|
||||
* @param filter The filter to use
|
||||
* @return The texture loaded
|
||||
* @throws IOException Indicates a failure to load the image
|
||||
*/
|
||||
public Texture getTexture(File source, boolean flipped,int filter) throws IOException {
|
||||
String resourceName = source.getAbsolutePath();
|
||||
InputStream in = new FileInputStream(source);
|
||||
|
||||
return getTexture(in, resourceName, flipped, filter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a texture from a specific file
|
||||
*
|
||||
* @param source The file to load the texture from
|
||||
* @param flipped True if we should flip the texture on the y axis while loading
|
||||
* @param filter The filter to use
|
||||
* @param transparent The colour to interpret as transparent or null if none
|
||||
* @return The texture loaded
|
||||
* @throws IOException Indicates a failure to load the image
|
||||
*/
|
||||
public Texture getTexture(File source, boolean flipped,int filter, int[] transparent) throws IOException {
|
||||
String resourceName = source.getAbsolutePath();
|
||||
InputStream in = new FileInputStream(source);
|
||||
|
||||
return getTexture(in, resourceName, flipped, filter, transparent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a texture from a resource location
|
||||
*
|
||||
* @param resourceName The location to load the texture from
|
||||
* @param flipped True if we should flip the texture on the y axis while loading
|
||||
* @param filter The filter to use when scaling the texture
|
||||
* @return The texture loaded
|
||||
* @throws IOException Indicates a failure to load the image
|
||||
*/
|
||||
public Texture getTexture(String resourceName, boolean flipped, int filter) throws IOException {
|
||||
InputStream in = ResourceLoader.getResourceAsStream(resourceName);
|
||||
|
||||
return getTexture(in, resourceName, flipped, filter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a texture from a resource location
|
||||
*
|
||||
* @param resourceName The location to load the texture from
|
||||
* @param flipped True if we should flip the texture on the y axis while loading
|
||||
* @param filter The filter to use when scaling the texture
|
||||
* @param transparent The colour to interpret as transparent or null if none
|
||||
* @return The texture loaded
|
||||
* @throws IOException Indicates a failure to load the image
|
||||
*/
|
||||
public Texture getTexture(String resourceName, boolean flipped, int filter, int[] transparent) throws IOException {
|
||||
InputStream in = ResourceLoader.getResourceAsStream(resourceName);
|
||||
|
||||
return getTexture(in, resourceName, flipped, filter, transparent);
|
||||
}
|
||||
/**
|
||||
* Get a texture from a image file
|
||||
*
|
||||
* @param in The stream from which we can load the image
|
||||
* @param resourceName The name to give this image in the internal cache
|
||||
* @param flipped True if we should flip the image on the y-axis while loading
|
||||
* @param filter The filter to use when scaling the texture
|
||||
* @return The texture loaded
|
||||
* @throws IOException Indicates a failure to load the image
|
||||
*/
|
||||
public Texture getTexture(InputStream in, String resourceName, boolean flipped, int filter) throws IOException {
|
||||
return getTexture(in, resourceName, flipped, filter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a texture from a image file
|
||||
*
|
||||
* @param in The stream from which we can load the image
|
||||
* @param resourceName The name to give this image in the internal cache
|
||||
* @param flipped True if we should flip the image on the y-axis while loading
|
||||
* @param filter The filter to use when scaling the texture
|
||||
* @param transparent The colour to interpret as transparent or null if none
|
||||
* @return The texture loaded
|
||||
* @throws IOException Indicates a failure to load the image
|
||||
*/
|
||||
public TextureImpl getTexture(InputStream in, String resourceName, boolean flipped, int filter, int[] transparent) throws IOException {
|
||||
if (deferred) {
|
||||
return new DeferredTexture(in, resourceName, flipped, filter, transparent);
|
||||
}
|
||||
|
||||
HashMap hash = texturesLinear;
|
||||
if (filter == SGL.GL_NEAREST) {
|
||||
hash = texturesNearest;
|
||||
}
|
||||
|
||||
String resName = resourceName;
|
||||
if (transparent != null) {
|
||||
resName += ":"+transparent[0]+":"+transparent[1]+":"+transparent[2];
|
||||
}
|
||||
resName += ":"+flipped;
|
||||
|
||||
if (holdTextureData) {
|
||||
TextureImpl tex = (TextureImpl) hash.get(resName);
|
||||
if (tex != null) {
|
||||
return tex;
|
||||
}
|
||||
} else {
|
||||
SoftReference ref = (SoftReference) hash.get(resName);
|
||||
if (ref != null) {
|
||||
TextureImpl tex = (TextureImpl) ref.get();
|
||||
if (tex != null) {
|
||||
return tex;
|
||||
} else {
|
||||
hash.remove(resName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// horrible test until I can find something more suitable
|
||||
try {
|
||||
GL.glGetError();
|
||||
} catch (NullPointerException e) {
|
||||
throw new RuntimeException("Image based resources must be loaded as part of init() or the game loop. They cannot be loaded before initialisation.");
|
||||
}
|
||||
|
||||
TextureImpl tex = getTexture(in, resourceName,
|
||||
SGL.GL_TEXTURE_2D,
|
||||
filter,
|
||||
filter, flipped, transparent);
|
||||
|
||||
tex.setCacheName(resName);
|
||||
if (holdTextureData) {
|
||||
hash.put(resName, tex);
|
||||
} else {
|
||||
hash.put(resName, new SoftReference(tex));
|
||||
}
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a texture from a image file
|
||||
*
|
||||
* @param in The stream from which we can load the image
|
||||
* @param resourceName The name to give this image in the internal cache
|
||||
* @param flipped True if we should flip the image on the y-axis while loading
|
||||
* @param target The texture target we're loading this texture into
|
||||
* @param minFilter The scaling down filter
|
||||
* @param magFilter The scaling up filter
|
||||
* @param transparent The colour to interpret as transparent or null if none
|
||||
* @return The texture loaded
|
||||
* @throws IOException Indicates a failure to load the image
|
||||
*/
|
||||
private TextureImpl getTexture(InputStream in,
|
||||
String resourceName,
|
||||
int target,
|
||||
int magFilter,
|
||||
int minFilter, boolean flipped, int[] transparent) throws IOException
|
||||
{
|
||||
// create the texture ID for this texture
|
||||
ByteBuffer textureBuffer;
|
||||
|
||||
LoadableImageData imageData = ImageDataFactory.getImageDataFor(resourceName);
|
||||
textureBuffer = imageData.loadImage(new BufferedInputStream(in), flipped, transparent);
|
||||
|
||||
int textureID = createTextureID();
|
||||
TextureImpl texture = new TextureImpl(resourceName, target, textureID);
|
||||
// bind this texture
|
||||
GL.glBindTexture(target, textureID);
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int texWidth;
|
||||
int texHeight;
|
||||
|
||||
boolean hasAlpha;
|
||||
|
||||
width = imageData.getWidth();
|
||||
height = imageData.getHeight();
|
||||
hasAlpha = imageData.getDepth() == 32;
|
||||
|
||||
texture.setTextureWidth(imageData.getTexWidth());
|
||||
texture.setTextureHeight(imageData.getTexHeight());
|
||||
|
||||
texWidth = texture.getTextureWidth();
|
||||
texHeight = texture.getTextureHeight();
|
||||
|
||||
IntBuffer temp = BufferUtils.createIntBuffer(16);
|
||||
GL.glGetInteger(SGL.GL_MAX_TEXTURE_SIZE, temp);
|
||||
int max = temp.get(0);
|
||||
if ((texWidth > max) || (texHeight > max)) {
|
||||
throw new IOException("Attempt to allocate a texture to big for the current hardware");
|
||||
}
|
||||
|
||||
int srcPixelFormat = hasAlpha ? SGL.GL_RGBA : SGL.GL_RGB;
|
||||
int componentCount = hasAlpha ? 4 : 3;
|
||||
|
||||
texture.setWidth(width);
|
||||
texture.setHeight(height);
|
||||
texture.setAlpha(hasAlpha);
|
||||
|
||||
if (holdTextureData) {
|
||||
texture.setTextureData(srcPixelFormat, componentCount, minFilter, magFilter, textureBuffer);
|
||||
}
|
||||
|
||||
GL.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, minFilter);
|
||||
GL.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, magFilter);
|
||||
|
||||
// produce a texture from the byte buffer
|
||||
GL.glTexImage2D(target,
|
||||
0,
|
||||
dstPixelFormat,
|
||||
get2Fold(width),
|
||||
get2Fold(height),
|
||||
0,
|
||||
srcPixelFormat,
|
||||
SGL.GL_UNSIGNED_BYTE,
|
||||
textureBuffer);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an empty texture
|
||||
*
|
||||
* @param width The width of the new texture
|
||||
* @param height The height of the new texture
|
||||
* @return The created empty texture
|
||||
* @throws IOException Indicates a failure to create the texture on the graphics hardware
|
||||
*/
|
||||
public Texture createTexture(final int width, final int height) throws IOException {
|
||||
return createTexture(width, height, SGL.GL_NEAREST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an empty texture
|
||||
*
|
||||
* @param width The width of the new texture
|
||||
* @param height The height of the new texture
|
||||
* @return The created empty texture
|
||||
* @throws IOException Indicates a failure to create the texture on the graphics hardware
|
||||
*/
|
||||
public Texture createTexture(final int width, final int height, final int filter) throws IOException {
|
||||
ImageData ds = new EmptyImageData(width, height);
|
||||
|
||||
return getTexture(ds, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a texture from a image file
|
||||
*
|
||||
* @param dataSource The image data to generate the texture from
|
||||
* @param filter The filter to use when scaling the texture
|
||||
* @return The texture created
|
||||
* @throws IOException Indicates the texture is too big for the hardware
|
||||
*/
|
||||
public Texture getTexture(ImageData dataSource, int filter) throws IOException
|
||||
{
|
||||
int target = SGL.GL_TEXTURE_2D;
|
||||
|
||||
ByteBuffer textureBuffer;
|
||||
textureBuffer = dataSource.getImageBufferData();
|
||||
|
||||
// create the texture ID for this texture
|
||||
int textureID = createTextureID();
|
||||
TextureImpl texture = new TextureImpl("generated:"+dataSource, target ,textureID);
|
||||
|
||||
int minFilter = filter;
|
||||
int magFilter = filter;
|
||||
boolean flipped = false;
|
||||
|
||||
// bind this texture
|
||||
GL.glBindTexture(target, textureID);
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int texWidth;
|
||||
int texHeight;
|
||||
|
||||
boolean hasAlpha;
|
||||
|
||||
width = dataSource.getWidth();
|
||||
height = dataSource.getHeight();
|
||||
hasAlpha = dataSource.getDepth() == 32;
|
||||
|
||||
texture.setTextureWidth(dataSource.getTexWidth());
|
||||
texture.setTextureHeight(dataSource.getTexHeight());
|
||||
|
||||
texWidth = texture.getTextureWidth();
|
||||
texHeight = texture.getTextureHeight();
|
||||
|
||||
int srcPixelFormat = hasAlpha ? SGL.GL_RGBA : SGL.GL_RGB;
|
||||
int componentCount = hasAlpha ? 4 : 3;
|
||||
|
||||
texture.setWidth(width);
|
||||
texture.setHeight(height);
|
||||
texture.setAlpha(hasAlpha);
|
||||
|
||||
IntBuffer temp = BufferUtils.createIntBuffer(16);
|
||||
GL.glGetInteger(SGL.GL_MAX_TEXTURE_SIZE, temp);
|
||||
int max = temp.get(0);
|
||||
if ((texWidth > max) || (texHeight > max)) {
|
||||
throw new IOException("Attempt to allocate a texture to big for the current hardware");
|
||||
}
|
||||
|
||||
if (holdTextureData) {
|
||||
texture.setTextureData(srcPixelFormat, componentCount, minFilter, magFilter, textureBuffer);
|
||||
}
|
||||
|
||||
GL.glTexParameteri(target, SGL.GL_TEXTURE_MIN_FILTER, minFilter);
|
||||
GL.glTexParameteri(target, SGL.GL_TEXTURE_MAG_FILTER, magFilter);
|
||||
|
||||
// produce a texture from the byte buffer
|
||||
GL.glTexImage2D(target,
|
||||
0,
|
||||
dstPixelFormat,
|
||||
get2Fold(width),
|
||||
get2Fold(height),
|
||||
0,
|
||||
srcPixelFormat,
|
||||
SGL.GL_UNSIGNED_BYTE,
|
||||
textureBuffer);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the closest greater power of 2 to the fold number
|
||||
*
|
||||
* @param fold The target number
|
||||
* @return The power of 2
|
||||
*/
|
||||
public static int get2Fold(int fold) {
|
||||
int ret = 2;
|
||||
while (ret < fold) {
|
||||
ret *= 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an integer buffer to hold specified ints
|
||||
* - strictly a utility method
|
||||
*
|
||||
* @param size how many int to contain
|
||||
* @return created IntBuffer
|
||||
*/
|
||||
public static IntBuffer createIntBuffer(int size) {
|
||||
ByteBuffer temp = ByteBuffer.allocateDirect(4 * size);
|
||||
temp.order(ByteOrder.nativeOrder());
|
||||
|
||||
return temp.asIntBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload all the textures loaded in this loader
|
||||
*/
|
||||
public void reload() {
|
||||
Iterator texs = texturesLinear.values().iterator();
|
||||
while (texs.hasNext()) {
|
||||
((TextureImpl) texs.next()).reload();
|
||||
}
|
||||
texs = texturesNearest.values().iterator();
|
||||
while (texs.hasNext()) {
|
||||
((TextureImpl) texs.next()).reload();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload a given texture blob
|
||||
*
|
||||
* @param texture The texture being reloaded
|
||||
* @param srcPixelFormat The source pixel format
|
||||
* @param componentCount The component count
|
||||
* @param minFilter The minification filter
|
||||
* @param magFilter The magnification filter
|
||||
* @param textureBuffer The pixel data
|
||||
* @return The ID of the newly created texture
|
||||
*/
|
||||
public int reload(TextureImpl texture, int srcPixelFormat, int componentCount,
|
||||
int minFilter, int magFilter, ByteBuffer textureBuffer) {
|
||||
int target = SGL.GL_TEXTURE_2D;
|
||||
int textureID = createTextureID();
|
||||
GL.glBindTexture(target, textureID);
|
||||
|
||||
GL.glTexParameteri(target, SGL.GL_TEXTURE_MIN_FILTER, minFilter);
|
||||
GL.glTexParameteri(target, SGL.GL_TEXTURE_MAG_FILTER, magFilter);
|
||||
|
||||
// produce a texture from the byte buffer
|
||||
GL.glTexImage2D(target,
|
||||
0,
|
||||
dstPixelFormat,
|
||||
texture.getTextureWidth(),
|
||||
texture.getTextureHeight(),
|
||||
0,
|
||||
srcPixelFormat,
|
||||
SGL.GL_UNSIGNED_BYTE,
|
||||
textureBuffer);
|
||||
|
||||
return textureID;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user