如何使用LWJGL加载图像以用作openGL纹理?

Bar*_*vbl 6 java opengl lwjgl

我正在尝试使用LWJGL库将图像作为openGL的纹理加载.从我到目前为止发现的,我需要将纹理作为ByteBuffer传递给openGL.我现在拥有的是一些正确加载图像的代码,并将其存储在BufferedImage对象中.问题是,我不知道如何从BufferedImage到包含正确格式的数据的ByteBuffer,以便与openGL一起使用(作为函数GL11.glTexImage2D()的输入).非常感谢帮助!

Ron*_*ero 6

以下是Space Invaders示例中的一种方法,它可以满足您的需求.(我认为)

/**
 * 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;
}
Run Code Online (Sandbox Code Playgroud)


Dis*_*lee 5

对于前面的答案,更直接的方法是使用image.getRGB颜色模型转换。以下是 Java 8文档的摘录getRGB

TYPE_INT_ARGB从图像数据的一部分返回默认 RGB 颜色模型 ( ) 和默认 sRGB 颜色空间中的整数像素数组。如果默认模型与图像 ColorModel 不匹配,则会发生颜色转换。使用此方法时,返回数据中每个颜色分量的精度只有 8 位。

public static ByteBuffer imageToBuffer(BufferedImage image) {
    int[] pixels = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth());
    ByteBuffer buffer = ByteBuffer.allocateDirect(pixels.length * 4);
    for (int pixel : pixels) {
        buffer.put((byte) ((pixel >> 16) & 0xFF));
        buffer.put((byte) ((pixel >> 8) & 0xFF));
        buffer.put((byte) (pixel & 0xFF));
        buffer.put((byte) (pixel >> 24) & 0xFF);
    }
    buffer.flip();
    return buffer;
}
Run Code Online (Sandbox Code Playgroud)

返回的缓冲区GL_RGBAGL_UNSIGNED_BYTE.