1

I'm working on a game and I have run into a problem where my OpenGL code wont delete a texture when I tell it to free every thing on shutdown, here is the exception:

Exception in thread "main" java.lang.NullPointerException
at org.lwjgl.opengl.GL11.glDeleteTextures(GL11.java:732)
at com.magicalrealmsofherith.OpenGL.releaseAll(OpenGL.java:29)
at com.magicalrealmsofherith.client.MRoH.stop(MRoH.java:100)
at com.magicalrealmsofherith.client.MRoH.run(MRoH.java:60)
at java.lang.Thread.run(Unknown Source)
at com.magicalrealmsofherith.client.MRoH.main(MRoH.java:22)

and here is my code(its a bit big):

public class OpenGL {

private static HashMap<String, Integer> textureMap = new HashMap<String, Integer>();
private static HashMap<Integer, BufferedImage> imageMap = new HashMap<Integer, BufferedImage>();
private static List<Integer> textureList = new ArrayList<Integer>();

public static void releaseAll()
{
    for(int i : textureList)
    {
        glDeleteTextures(i);
    }
    textureList.clear();
    imageMap.clear();
    textureMap.clear();
}

public static int getTextureId(String texture) {
    if(textureMap.containsKey(texture))
        return textureMap.get(texture);
    else
    {
        setupTexture(texture);
        return textureMap.get(texture);
    }
}

public static void bindTexutre(String texture) {
    bindTexture(getTextureId(texture));
}

public static void bindTexture(int textureId){
    glBindTexture(GL_TEXTURE_2D, textureId);
}

public static void setupTexture(String textureName) {

    BufferedImage texture;
    try
    {
        texture = ImageIO.read((OpenGL.class.getClassLoader()).getResourceAsStream(textureName));
    }
    catch(Exception e)
    {
        try
        {
            texture = ImageIO.read(new File(textureName));
        }
        catch(Exception ex)
        {
            texture = new BufferedImage(64, 64, 2);
            Graphics g = texture.getGraphics();
            g.setColor(Color.white);
            g.fillRect(0, 0, 64, 64);
            g.setColor(Color.black);
            g.drawString("texturemiss", 1, 10);
            g.dispose();
        }
    }

    setupTexture(texture, textureName);
}

public static void setupTexture(BufferedImage texture, String textureName) {
    int id = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, id);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.getWidth(), texture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, decodePNG(texture, true));
    textureMap.put(textureName, id);
    imageMap.put(id, texture);
    textureList.add(id);
    glBindTexture(GL_TEXTURE_2D, 0);
}

public static ByteBuffer decodePNG(BufferedImage texture, boolean alpha) {
    ByteBuffer buffer = BufferUtils.createByteBuffer(texture.getWidth() * texture.getHeight() * (alpha == true ? 4 : 3));
    int[] pixels = new int[texture.getWidth() * texture.getHeight()];
    texture.getRGB(0, 0, texture.getWidth(), texture.getHeight(), pixels, 0, texture.getWidth());
    for(int y = 0; y < texture.getHeight(); y++)
    {
        for(int x = 0; x < texture.getWidth(); x++)
        {
            int pixel = pixels[y * texture.getWidth() + x];
            buffer.put((byte) ((pixel >> 16) & 0xFF));
            buffer.put((byte) ((pixel >> 8) & 0xFF));
            buffer.put((byte) (pixel & 0xFF));
            if(alpha)
                buffer.put((byte) ((pixel >> 24) & 0xFF));
        }
    }
    buffer.flip();
    return buffer;
}
}
Tim
  • 35,413
  • 11
  • 95
  • 121
Liam Haworth
  • 848
  • 1
  • 9
  • 27
  • 1
    At what point in the shutdown is this getting called? That you're getting an NPE inside LWJGL source makes me wonder if it's being called after the context has been trashed. Maybe try calling releaseAll earlier in the shutdown sequence to see if it makes a difference? Either that or DL the lwjgl source and see what's at that line. – Tim Jun 02 '12 at 08:14
  • Thanks, I fixed it; I was releasing after I destroyed the display, I needed to do it before – Liam Haworth Jun 02 '12 at 08:18

1 Answers1

2

I fixed my own problem, with the help of Tim. for anybody else out there who's going to use this code; you have to call OpenGL.releaseAll(); before Display.destroy();

Liam Haworth
  • 848
  • 1
  • 9
  • 27