How do I load an image for use as an openGL texture with LWJGL?

Here's a method from the Space Invaders example that does what you want. (I think)

/**
 * Convert the buffered image to a texture
 */
private ByteBuffer convertImageData(BufferedImage bufferedImage) {
    ByteBuffer imageBuffer;
    WritableRaster raster;
    BufferedImage texImage;

    ColorModel glAlphaColorModel = new ComponentColorModel(ColorSpace
            .getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 8 },
            true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);

    raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
            bufferedImage.getWidth(), bufferedImage.getHeight(), 4, null);
    texImage = new BufferedImage(glAlphaColorModel, raster, true,
            new Hashtable());

    // copy the source image into the produced image
    Graphics g = texImage.getGraphics();
    g.setColor(new Color(0f, 0f, 0f, 0f));
    g.fillRect(0, 0, 256, 256);
    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;
}

I used the solution above by Ron but the colors of the image when applied as a texture were incorrect, which means, the accepted solution will probably not produce same results for all kinds of images.

Trying to fix the problem with the color, I tried to use the ColorModel of the original BufferedImage, which can be accessed by calling the BufferedImage#getColorModel. But, it gave me an exception that the ColorModel of the original image is incompatible with the WritableRaster object.

I looked for a solution for this and I found this one. Instead of calling Raster.createInterleavedRaster to create a WritableRaster, I used ColorModel#createCompatibleWritableRaster.

Hope this helps. Here's the code:

public static ByteBuffer load(BufferedImage bufferedImage) {

    WritableRaster raster = bufferedImage.getColorModel().createCompatibleWritableRaster
        (bufferedImage.getWidth(), bufferedImage.getHeight());
    BufferedImage textureImage = new BufferedImage(bufferedImage.getColorModel(), raster,
        true, new Hashtable<>());

    Graphics graphics = textureImage.getGraphics();
    graphics.setColor(new Color(0, 0, 0));
    graphics.fillRect(0, 0, 256, 256);
    graphics.drawImage(bufferedImage, 0, 0, null);

    byte[] data = ((DataBufferByte) textureImage.getRaster().getDataBuffer()).getData();

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

    return imageBuffer;
}

Tags:

Java

Opengl

Lwjgl