Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在opengl中处理纹理并将其切割成多个瓷砖_Java_Opengl_Textures_Lwjgl - Fatal编程技术网

Java 在opengl中处理纹理并将其切割成多个瓷砖

Java 在opengl中处理纹理并将其切割成多个瓷砖,java,opengl,textures,lwjgl,Java,Opengl,Textures,Lwjgl,我的问题是: 我在openGL(LWJGL)中加载了一个图像作为纹理,每次调用draw方法时,我都能够选择要显示的瓷砖集的位置(在我的例子中是精灵动画的特定帧),我想知道,如果它是最好的阅读整个瓷砖集,并将其切割成较小的瓷砖集只有一个精灵或是相同的处理整个图像 实际上,我在每个瓷砖的纹理中加载整个图像,每次绘制时,每个瓷砖都在整个瓷砖集上使用GL_四边形 瓷砖集可以包含许多瓷砖和许多动画瓷砖 我曾经处理图像,读取一个大图像并将其放入tileset对象中,然后分离每个瓷砖,切割图像并将切割的部分放

我的问题是: 我在openGL(LWJGL)中加载了一个图像作为纹理,每次调用draw方法时,我都能够选择要显示的瓷砖集的位置(在我的例子中是精灵动画的特定帧),我想知道,如果它是最好的阅读整个瓷砖集,并将其切割成较小的瓷砖集只有一个精灵或是相同的处理整个图像

实际上,我在每个瓷砖的纹理中加载整个图像,每次绘制时,每个瓷砖都在整个瓷砖集上使用GL_四边形

瓷砖集可以包含许多瓷砖和许多动画瓷砖

我曾经处理图像,读取一个大图像并将其放入tileset对象中,然后分离每个瓷砖,切割图像并将切割的部分放入瓷砖中

我不明白它的纹理是否相同

在这种情况下,从现有问题的切面开始创建新纹理的方法是什么

我想做的是:

地图加载平铺集 TILESET加载整个图像 将图像剪切成许多小图像(纹理) 瓷砖只有一个小纹理,是大纹理的一部分

每次绘制时,每个瓷砖将仅处理一个较小的瓷砖。这是正确的还是相同的,如果我将整个瓷砖集传递给每个瓷砖,告诉它只向用户显示哪个部分

这是我的TileSet课程:

package mh.map;

import java.awt.Color;
import java.awt.Image;
import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Vector;

import mh.GameWindow;
import tiled.util.TileCutter;

public class TileSet implements Iterable<Tile> {
private String              base;
final private Vector<Tile>  tiles   = new Vector<Tile>();
private long                tilebmpFileLastModified;
private TileCutter          tileCutter;
private Rectangle           tileDimensions;
private int                 tileSpacing;
private int                 tileMargin;
private int                 tilesPerRow;
private String              externalSource;
private File                tilebmpFile;
private String              name;
private Color               transparentColor;
private Image               tileSetImage;

private Texture             texture;

public TileSet() {
    this.tileDimensions = new Rectangle();
}

public void importTileTexture(String ref, int width, int height, int spacing, int margin) {
    try {
        this.texture = GameWindow.getTextureLoader().getTexture(ref);
        int texWidth = this.texture.getImageWidth();
        int texHeight = this.texture.getImageHeight();
        int tilePerRow = texWidth / width;
        int rows = texHeight / height;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < tilePerRow; j++) {
                Tile t = new Tile(this, j, i);
                this.addNewTile(t);
            }
        }

    } catch (IOException e) {
        System.err.println("Unable to load texture: " + ref);
        e.printStackTrace();
    }
}

public int addTile(Tile t) {
    if (t.getId() < 0) {
        t.setId(this.tiles.size());
    }


    if (this.tileDimensions.width < t.getWidth()) {
        this.tileDimensions.width = t.getWidth();
    }

    if (this.tileDimensions.height < t.getHeight()) {
        this.tileDimensions.height = t.getHeight();
    }

    this.tiles.add(t);
    t.setTileSet(this);

    return t.getId();
}

public void addNewTile(Tile t) {
    t.setId(-1);
    this.addTile(t);
}

public void removeTile(int i) {
    this.tiles.set(i, null);
}

public int size() {
    return this.tiles.size();
}

public int getMaxTileId() {
    return this.tiles.size() - 1;
}

public Tile getTile(int i) {
    try {
        return this.tiles.get(i);
    } catch (ArrayIndexOutOfBoundsException a) {
    }
    return null;
}

public Tile getFirstTile() {
    Tile ret = null;
    int i = 0;
    while ((ret == null) && (i <= this.getMaxTileId())) {
        ret = this.getTile(i);
        i++;
    }
    return ret;
}

public Texture getTexture() {
    return this.texture;
}

}
这是textureloader:

package mh.map;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import org.lwjgl.opengl.GL11;

/**
 * @author Kevin Glass
 * @author Brian Matzon
 * @author Gianmarco Laggia
 */
public class TextureLoader {
/** The table of textures that have been loaded in this loader */
private final HashMap<String, Texture>  table   = new HashMap<String, Texture>();

/** The colour model including alpha for the GL image */
private final ColorModel                glAlphaColorModel;

/** The colour model for the GL image */
private final ColorModel                glColorModel;

/**
 * Create a new texture loader based on the game panel
 */
public TextureLoader() {
    this.glAlphaColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 8 }, true, false,
            Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);

    this.glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 0 }, false, false, Transparency.OPAQUE,
            DataBuffer.TYPE_BYTE);
}

/**
 * Create a new texture ID
 * 
 * @return A new texture ID
 */
private int createTextureID() {
    IntBuffer tmp = this.createIntBuffer(1);
    GL11.glGenTextures(tmp);
    return tmp.get(0);
}

/**
 * Load a texture
 * 
 * @param resourceName
 *            The location of the resource to load
 * @return The loaded texture
 * @throws IOException
 *             Indicates a failure to access the resource
 */
public Texture getTexture(String resourceName) throws IOException {
    Texture tex = this.table.get(resourceName);

    if (tex != null) {
        return tex;
    }

    tex = this.getTexture(resourceName, GL11.GL_TEXTURE_2D, // target
            GL11.GL_RGBA, // dst pixel format
            GL11.GL_LINEAR, // min filter (unused)
            GL11.GL_LINEAR);

    this.table.put(resourceName, tex);

    return tex;
}

/**
 * Load a texture into OpenGL from a image reference on disk.
 * 
 * @param resourceName
 *            The location of the resource to load
 * @param target
 *            The GL target to load the texture against
 * @param dstPixelFormat
 *            The pixel format of the screen
 * @param minFilter
 *            The minimising filter
 * @param magFilter
 *            The magnification filter
 * @return The loaded texture
 * @throws IOException
 *             Indicates a failure to access the resource
 */
public Texture getTexture(String resourceName, int target, int dstPixelFormat, int minFilter, int magFilter) throws IOException {
    int srcPixelFormat = 0;

    // create the texture ID for this texture
    int textureID = this.createTextureID();
    Texture texture = new Texture(target, textureID);

    // bind this texture
    GL11.glBindTexture(target, textureID);

    BufferedImage bufferedImage = this.loadImage(resourceName);
    texture.setWidth(bufferedImage.getWidth());
    texture.setHeight(bufferedImage.getHeight());

    if (bufferedImage.getColorModel().hasAlpha()) {
        srcPixelFormat = GL11.GL_RGBA;
    } else {
        srcPixelFormat = GL11.GL_RGB;
    }

    // convert that image into a byte buffer of texture data
    ByteBuffer textureBuffer = this.convertImageData(bufferedImage, texture);

    if (target == GL11.GL_TEXTURE_2D) {
        GL11.glTexParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, minFilter);
        GL11.glTexParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, magFilter);
    }

    // produce a texture from the byte buffer
    GL11.glTexImage2D(target, 0, dstPixelFormat, this.get2Fold(bufferedImage.getWidth()), this.get2Fold(bufferedImage.getHeight()), 0, srcPixelFormat,
            GL11.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
 */
private int get2Fold(int fold) {
    int ret = 2;
    while (ret < fold) {
        ret *= 2;
    }
    return ret;
}

/**
 * Convert the buffered image to a texture
 * 
 * @param bufferedImage
 *            The image to convert to a texture
 * @param texture
 *            The texture to store the data into
 * @return A buffer containing the data
 */
private ByteBuffer convertImageData(BufferedImage bufferedImage, Texture texture) {
    ByteBuffer imageBuffer = null;
    WritableRaster raster;
    BufferedImage texImage;

    int texWidth = 2;
    int texHeight = 2;

    // find the closest power of 2 for the width and height
    // of the produced texture
    while (texWidth < bufferedImage.getWidth()) {
        texWidth *= 2;
    }
    while (texHeight < bufferedImage.getHeight()) {
        texHeight *= 2;
    }

    texture.setTextureHeight(texHeight);
    texture.setTextureWidth(texWidth);

    // create a raster that can be used by OpenGL as a source
    // for a texture
    if (bufferedImage.getColorModel().hasAlpha()) {
        raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texWidth, texHeight, 4, null);
        texImage = new BufferedImage(this.glAlphaColorModel, raster, false, new Hashtable<String, Texture>());
    } else {
        raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texWidth, texHeight, 3, null);
        texImage = new BufferedImage(this.glColorModel, raster, false, new Hashtable<String, Texture>());
    }

    // copy the source image into the produced image
    Graphics g = texImage.getGraphics();
    g.setColor(new Color(0f, 0f, 0f, 0f));
    g.fillRect(0, 0, texWidth, texHeight);
    g.drawImage(bufferedImage, 0, 0, null);

    // build a byte buffer from the temporary image
    // that be used by OpenGL to produce a texture.
    byte[] data = ((DataBufferByte) texImage.getRaster().getDataBuffer()).getData();

    imageBuffer = ByteBuffer.allocateDirect(data.length);
    imageBuffer.order(ByteOrder.nativeOrder());
    imageBuffer.put(data, 0, data.length);
    imageBuffer.flip();

    return imageBuffer;
}

/**
 * Load a given resource as a buffered image
 * 
 * @param ref
 *            The location of the resource to load
 * @return The loaded buffered image
 * @throws IOException
 *             Indicates a failure to find a resource
 */
private BufferedImage loadImage(String ref) throws IOException {
    URL url = TextureLoader.class.getClassLoader().getResource(ref);
    if (url == null) {
        url = new URL("file:"+ref);
//          throw new IOException("Cannot find: " + ref);
    }
    System.out.println("URL:" + url);
    BufferedImage bufferedImage = ImageIO.read(new BufferedInputStream(url.openStream()));//this.getClass().getClassLoader().getResourceAsStream(ref)));

    return bufferedImage;
}

/**
 * Creates an integer buffer to hold specified ints - strictly a utility method
 * 
 * @param size
 *            how many int to contain
 * @return created IntBuffer
 */
protected IntBuffer createIntBuffer(int size) {
    ByteBuffer temp = ByteBuffer.allocateDirect(4 * size);
    temp.order(ByteOrder.nativeOrder());

    return temp.asIntBuffer();
}
}
包mh.map;
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Transparency;
导入java.awt.color.ColorSpace;
导入java.awt.image.buffereImage;
导入java.awt.image.ColorModel;
导入java.awt.image.ComponentColorModel;
导入java.awt.image.DataBuffer;
导入java.awt.image.DataBufferByte;
导入java.awt.image.graster;
导入java.awt.image.WritableRaster;
导入java.io.BufferedInputStream;
导入java.io.IOException;
导入java.net.URL;
导入java.nio.ByteBuffer;
导入java.nio.ByteOrder;
导入java.nio.IntBuffer;
导入java.util.HashMap;
导入java.util.Hashtable;
导入javax.imageio.imageio;
导入org.lwjgl.opengl.GL11;
/**
*@作者凯文·格拉斯
*@作者布莱恩·马特松
*@作者Gianmarco Laggia
*/
公共类纹理阅读器{
/**在此加载程序中加载的纹理表*/
private final HashMap table=new HashMap();
/**GL图像的包含alpha的颜色模型*/
私人最终颜色模型glAlphaColorModel;
/**GL图像的颜色模型*/
私有最终颜色模型glColorModel;
/**
*基于游戏面板创建一个新的纹理加载器
*/
公共纹理阅读器(){
this.glAlphaColorModel=newcomponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),newint[]{8,8,8,8},true,false,
Transparency.Transparency,DataBuffer.TYPE_BYTE);
this.glColorModel=new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),new int[]{8,8,8,0},false,false,Transparency.不透明,
DataBuffer.TYPE_字节);
}
/**
*创建一个新的纹理ID
* 
*@返回一个新的纹理ID
*/
私有int createTextureID(){
IntBuffer tmp=this.createIntBuffer(1);
GL11.glGenTextures(tmp);
返回tmp.get(0);
}
/**
*加载纹理
* 
*@param resourceName
*要加载的资源的位置
*@返回加载的纹理
*@抛出异常
*表示访问资源失败
*/
公共纹理getTexture(字符串resourceName)引发IOException{
纹理tex=this.table.get(resourceName);
如果(tex!=null){
返回tex;
}
tex=this.getTexture(resourceName,GL11.GL\u TEXTURE\u 2D,//target
GL11.GL_RGBA,//dst像素格式
GL11.GL_线性,//最小过滤器(未使用)
GL11.GL_线性);
this.table.put(resourceName,tex);
返回tex;
}
/**
*从磁盘上的图像引用将纹理加载到OpenGL中。
* 
*@param resourceName
*要加载的资源的位置
*@param目标
*要加载纹理的GL目标
*@param DST像素格式
*屏幕的像素格式
*@param-minFilter
*最小化滤波器
*@param磁过滤器
*放大滤波器
*@返回加载的纹理
*@抛出异常
*表示访问资源失败
*/
公共纹理getTexture(字符串resourceName、int-target、int-dstPixelFormat、int-minFilter、int-magFilter)引发IOException{
int srcPixelFormat=0;
//创建此纹理的纹理ID
int textureID=this.createTextureID();
纹理=新纹理(目标,纹理ID);
//绑定此纹理
GL11.glBindTexture(目标,textureID);
BuffereImage BuffereImage=this.loadImage(resourceName);
setWidth(buffereImage.getWidth());
setHeight(bufferedImage.getHeight());
if(buffereImage.getColorModel().hasAlpha()){
srcPixelFormat=GL11.GL_RGBA;
}否则{
srcPixelFormat=GL11.GL_RGB;
}
//将该图像转换为纹理数据的字节缓冲区
ByteBuffer textureBuffer=this.convertImageData(BuffereImage,纹理);
如果(目标==GL11.GL\U纹理\U 2D){
GL11.glTexParameteri(目标,GL11.GL\u纹理\u最小过滤器,最小过滤器);
GL11.glTexParameteri(目标、GL11.GL\u纹理、MAG\u过滤器、magFilter);
}
//从字节缓冲区生成纹理
GL11.glTexImage2D(目标,0,dstPixelFormat,this.get2Fold(bufferedImage.getWidth()),this.get2Fold(bufferedImage.getHeight()),0,srcPixelFormat,
GL11.GL_无符号字节,textureBuffer);
返回纹理;
}
/**
*获得与折叠数最接近的2的最大幂
* 
*@param褶皱
*目标号码
*@返回2的力量
*/
私有int-get2Fold(int-fold){
int-ret=2;
while(retpackage mh.map;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import org.lwjgl.opengl.GL11;

/**
 * @author Kevin Glass
 * @author Brian Matzon
 * @author Gianmarco Laggia
 */
public class TextureLoader {
/** The table of textures that have been loaded in this loader */
private final HashMap<String, Texture>  table   = new HashMap<String, Texture>();

/** The colour model including alpha for the GL image */
private final ColorModel                glAlphaColorModel;

/** The colour model for the GL image */
private final ColorModel                glColorModel;

/**
 * Create a new texture loader based on the game panel
 */
public TextureLoader() {
    this.glAlphaColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 8 }, true, false,
            Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);

    this.glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 0 }, false, false, Transparency.OPAQUE,
            DataBuffer.TYPE_BYTE);
}

/**
 * Create a new texture ID
 * 
 * @return A new texture ID
 */
private int createTextureID() {
    IntBuffer tmp = this.createIntBuffer(1);
    GL11.glGenTextures(tmp);
    return tmp.get(0);
}

/**
 * Load a texture
 * 
 * @param resourceName
 *            The location of the resource to load
 * @return The loaded texture
 * @throws IOException
 *             Indicates a failure to access the resource
 */
public Texture getTexture(String resourceName) throws IOException {
    Texture tex = this.table.get(resourceName);

    if (tex != null) {
        return tex;
    }

    tex = this.getTexture(resourceName, GL11.GL_TEXTURE_2D, // target
            GL11.GL_RGBA, // dst pixel format
            GL11.GL_LINEAR, // min filter (unused)
            GL11.GL_LINEAR);

    this.table.put(resourceName, tex);

    return tex;
}

/**
 * Load a texture into OpenGL from a image reference on disk.
 * 
 * @param resourceName
 *            The location of the resource to load
 * @param target
 *            The GL target to load the texture against
 * @param dstPixelFormat
 *            The pixel format of the screen
 * @param minFilter
 *            The minimising filter
 * @param magFilter
 *            The magnification filter
 * @return The loaded texture
 * @throws IOException
 *             Indicates a failure to access the resource
 */
public Texture getTexture(String resourceName, int target, int dstPixelFormat, int minFilter, int magFilter) throws IOException {
    int srcPixelFormat = 0;

    // create the texture ID for this texture
    int textureID = this.createTextureID();
    Texture texture = new Texture(target, textureID);

    // bind this texture
    GL11.glBindTexture(target, textureID);

    BufferedImage bufferedImage = this.loadImage(resourceName);
    texture.setWidth(bufferedImage.getWidth());
    texture.setHeight(bufferedImage.getHeight());

    if (bufferedImage.getColorModel().hasAlpha()) {
        srcPixelFormat = GL11.GL_RGBA;
    } else {
        srcPixelFormat = GL11.GL_RGB;
    }

    // convert that image into a byte buffer of texture data
    ByteBuffer textureBuffer = this.convertImageData(bufferedImage, texture);

    if (target == GL11.GL_TEXTURE_2D) {
        GL11.glTexParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, minFilter);
        GL11.glTexParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, magFilter);
    }

    // produce a texture from the byte buffer
    GL11.glTexImage2D(target, 0, dstPixelFormat, this.get2Fold(bufferedImage.getWidth()), this.get2Fold(bufferedImage.getHeight()), 0, srcPixelFormat,
            GL11.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
 */
private int get2Fold(int fold) {
    int ret = 2;
    while (ret < fold) {
        ret *= 2;
    }
    return ret;
}

/**
 * Convert the buffered image to a texture
 * 
 * @param bufferedImage
 *            The image to convert to a texture
 * @param texture
 *            The texture to store the data into
 * @return A buffer containing the data
 */
private ByteBuffer convertImageData(BufferedImage bufferedImage, Texture texture) {
    ByteBuffer imageBuffer = null;
    WritableRaster raster;
    BufferedImage texImage;

    int texWidth = 2;
    int texHeight = 2;

    // find the closest power of 2 for the width and height
    // of the produced texture
    while (texWidth < bufferedImage.getWidth()) {
        texWidth *= 2;
    }
    while (texHeight < bufferedImage.getHeight()) {
        texHeight *= 2;
    }

    texture.setTextureHeight(texHeight);
    texture.setTextureWidth(texWidth);

    // create a raster that can be used by OpenGL as a source
    // for a texture
    if (bufferedImage.getColorModel().hasAlpha()) {
        raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texWidth, texHeight, 4, null);
        texImage = new BufferedImage(this.glAlphaColorModel, raster, false, new Hashtable<String, Texture>());
    } else {
        raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texWidth, texHeight, 3, null);
        texImage = new BufferedImage(this.glColorModel, raster, false, new Hashtable<String, Texture>());
    }

    // copy the source image into the produced image
    Graphics g = texImage.getGraphics();
    g.setColor(new Color(0f, 0f, 0f, 0f));
    g.fillRect(0, 0, texWidth, texHeight);
    g.drawImage(bufferedImage, 0, 0, null);

    // build a byte buffer from the temporary image
    // that be used by OpenGL to produce a texture.
    byte[] data = ((DataBufferByte) texImage.getRaster().getDataBuffer()).getData();

    imageBuffer = ByteBuffer.allocateDirect(data.length);
    imageBuffer.order(ByteOrder.nativeOrder());
    imageBuffer.put(data, 0, data.length);
    imageBuffer.flip();

    return imageBuffer;
}

/**
 * Load a given resource as a buffered image
 * 
 * @param ref
 *            The location of the resource to load
 * @return The loaded buffered image
 * @throws IOException
 *             Indicates a failure to find a resource
 */
private BufferedImage loadImage(String ref) throws IOException {
    URL url = TextureLoader.class.getClassLoader().getResource(ref);
    if (url == null) {
        url = new URL("file:"+ref);
//          throw new IOException("Cannot find: " + ref);
    }
    System.out.println("URL:" + url);
    BufferedImage bufferedImage = ImageIO.read(new BufferedInputStream(url.openStream()));//this.getClass().getClassLoader().getResourceAsStream(ref)));

    return bufferedImage;
}

/**
 * Creates an integer buffer to hold specified ints - strictly a utility method
 * 
 * @param size
 *            how many int to contain
 * @return created IntBuffer
 */
protected IntBuffer createIntBuffer(int size) {
    ByteBuffer temp = ByteBuffer.allocateDirect(4 * size);
    temp.order(ByteOrder.nativeOrder());

    return temp.asIntBuffer();
}
}
public class Tileset {

 private int tilesetImageHandle;

 private ArrayList<Tile> tiles;

 public Tile getTile(int tileIndex) {
    return tiles.get(tileIndex);
 }

 public void bindTexture() {
    glBindTexture(tilesetImageHandle);
 }

 // Methods to retrieve tileset subimage offsets in x and y directions

}

public class Tile {
 private Tileset tileset;
 private float u, v;

 public Tile(Tileset tileset, float u, float v)  {
    this.tileset = tileset;
    this.u = u;
    this.v = v;
 }

 public void draw(Point location) {
    tileset.bindTexture();

    glPushMatrix(GL_MODEL_VIEW_MATRIX);
    glTranslate2f(location.x, location.y);

    glBegin(GL_QUADS);

    glCoord2f(0.0, 0.0);
    glTexCoord2f(u, v);
    glCoord2f(0.0, 1.0);
    glTexCoord2f(u, v + tileset.getTilesetOffsetY());
    glCoord2f(tileset.getTileDimX(), tileset.getTileDimY());
    glTexCoord2f(u + tileset.getTilesetOffsetX(), v + tileset.getTilesetOffsetY());
    glCoord2f(1.0, 0.0);
    glTexCoord2f(u + tileset.getTilesetOffsetX(), v);

    glEnd();

    glPopMatrix(GL_MODEL_VIEW_MATRIX);
 }
}