Skip to content

Practice 01 Loading Images

squid233 edited this page Mar 20, 2023 · 5 revisions

We often need to load images such as creating a textures. There are 2 methods to do it.

Using STB

Using STB to load images is very easy.

// ref pw, ph, pc for width, height and components
int[] pw = new int[1], ph = new int[1], pc = new int[1];
var img = STBImage.load("Local.png", pw, ph, pc, STBImage.RGB_ALPHA);
GL.texImage2D(..., img);
STBImage.free(img);

or

try (var stack = MemoryStack.stackPush()) {
    var pw = stack.malloc(JAVA_INT);
    var ph = stack.malloc(JAVA_INT);
    var pc = stack.malloc(JAVA_INT);
    var img = STBImage.load("Local.png", pw, ph, pc, STBImage.RGB_ALPHA);
    GL.texImage2D(..., img);
    STBImage.free(img);
}

Note that you always need to use STBImage.free to release the memory, because OverrunGL doesn't track it in the debug allocator.

Using BufferedImage (Not Recommended)

Using BufferedImage to load images on classpath is more easy than STB, but seems like slower.

Note: It’s default little-endian in C, so if you pass RGBA type to C functions, the array must be order in ABGR.

// Get input stream
try (var is = ClassLoader.getSystemResource("Classpath.png")) {
    var img = ImageIO.read(is);
    // ---
    // 1. GL_RGBA
    int[] arr = img.getRGB(0, 0, w, h, new int[w * h], 0, w);
    // Convert to ABGR
    for (int i = 0; i < arr.length; i++) {
        int a = arr[i] >> 24 & 0xff;
        int r = arr[i] >> 16 & 0xff;
        int g = arr[i] >> 8 & 0xff;
        int b = arr[i] & 0xff;
        arr[i] = a << 24 | b << 16 | g << 8 | r;
    }
    GL.texImage2D(..., GL_RGBA, arr);
    // ---
    // 2. GL_BGRA
    int[] arr = img.getRGB(0, 0, w, h, new int[w * h], 0, w);
    // Required order is ARGB so no need to re-order
    GL.texImage2D(..., GL_BGRA, arr);
}
Clone this wiki locally