Hot questions for Using Lightweight Java Game Library in bufferedimage

Question:

I'm experiencing something really strange, and I don't know what's causing it at all. This is the problematic line of code:

BufferedImage out = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);

Upon calling this, all threads freeze and everything stops. I've tried putting this in its own thread and the main thread, the same thing occurs. I am using LWJGL3, so that might be an issue, but I don't see how it could be.

Edit: Does not occur in a blank project without LWJGL in or out of -XstartOnFirstThread


Answer:

Ok! I found the solution. Turns out, all it takes is the following JVM argument: -Djava.awt.headless=true You also have to make sure that you aren't running it in the main thread, you have to do it outside of the thread where GLFW is initialized.

All of this only applies if you are running LWJGL on Mac, Linux and Windows don't have this issue.

Question:

Is there a simple way to get an rgba int[] from an argb BufferedImage? I need it to be converted for opengl, but I don't want to have to iterate through the pixel array and convert it myself.


Answer:

OpenGL 1.2+ supports a GL_BGRA pixel format and reversed packed pixels.

On the surface BGRA does not sound like what you want, but let me explain.

Calls like glTexImage2D (...) do what is known as pixel transfer, which involves packing and unpacking image data. During the process of pixel transfer, data conversion may be performed, special alignment rules may be followed, etc. The data conversion step is what we are particularly interested in here; you can transfer pixels in a number of different layouts besides the obvious RGBA component order.

If you reverse the byte order (e.g. data type = GL_UNSIGNED_INT_8_8_8_8_REV) together with a GL_BGRA format, you will effectively transfer ARGB pixels without any real effort on your part.

Example glTexImage2D (...) call:
glTexImage2D (..., GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image);

The usual use-case for _REV packed data types is handling endian differences between different processors, but it also comes in handy when you want to reverse the order of components in an image (since there is no such thing as GL_ARGB).

Do not convert things for OpenGL - it is perfectly capable of doing this by itself.

Question:

I'm using a piece of code to grab a screenshot of my application screen for a group project. On my Macbook Pro the code freezes the screen whereas on my teammates's PC's (all Windows) it runs just fine and exports a .png file in their root dir.

The code
public void screenShot(){
    //Creating an rbg array of total pixels
    int[] pixels = new int[WIDTH * HEIGHT];
    int bindex;
    // allocate space for RBG pixels
    ByteBuffer fb = ByteBuffer.allocateDirect(WIDTH * HEIGHT * 3);

    // grab a copy of the current frame contents as RGB
    glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, fb);

    // convert RGB data in ByteBuffer to integer array
    for (int i=0; i < pixels.length; i++) {
        bindex = i * 3;
        pixels[i] =
                ((fb.get(bindex) << 16))  +
                        ((fb.get(bindex+1) << 8))  +
                        ((fb.get(bindex+2) << 0));
    }
    //Allocate colored pixel to buffered Image
    BufferedImage imageIn = null;
    try{
        //THIS LINE 
        imageIn = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);
        //THIS LINE ^^^^^ 
        imageIn.setRGB(0, 0, WIDTH, HEIGHT, pixels, 0 , WIDTH);
    } catch (Exception e) {
        e.printStackTrace();
    }

The problem

When debugging I can see that when stepping in at this line

imageIn = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);

the debugger doesn't go to the BufferedImage constructor but to GLFWKeyCallbackI.callback() and after that to GLFWCursorEnterCallbackI.callback(). After this it stops altogether.

What I tried

In my main class above all the rest of the code making a buffered Image as such:

BufferedImage imageIn = new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB);

It also freezes the simulation but it does seems to actually execute the line.


I'm not sure what else I could try, I saw a few other posts ranging between 2005 and today asking similar Mac questions without an answer.


Answer:

I delved a bit deeper and discovered the issue. As mentioned in a comment here if I provide this VM option "-Djava.awt.headless=true" it seems to fix the issue.