Switching to LWJGL 3

I test it on MacOS so far it works fine for me.

1 Like

This is a valid point too. I think I had the same results awhile back. One thing could be to manually compare the window size and the framebuffer size. Framebuffer size is the actual size in pixels… and the window size equals to the mouse coordinates? So the difference would be the mouse scaling factor?

1 Like

another scenario to consider is an external monitor attached to your mac but reading through your PR i assume it would work correctly since both, the framebuffersize and contentscale have callbacks added that should fire and handle the changes the moment the window switches from one monitor to the other

from what i get GLFW reports most values in screen coordinates (the window size as well as the cursor position for example), while the framebuffersize is in pixels
i did some quick tests on windows 10: create a resizable window, resize it, minimize it, restore it, change the contentscale settings in windows10 for this monitor to 125%, minimize the window again, restore it again, move it over to the second monitor that still has contentscale of 100% and move it back to the primary monitor.
in the code where the framebuffersize and windowsize callbacks are set, a comment states that the windowsize callback might not be called and this is still true for me, additionally the windowcontentscale callback is also never called. Basically we only get the framebuffersize callback (the code in the callback already reads the window size) and in my tests the framebuffersize as well as windowsize always is the same (i would expect this initially when the contentscale is 100%, but i thought they would differ after changing the contentscale) and starting the application with contentscale already set to 125% both values are still always the same, in this case however the initial call to glfwGetWindowContentScale returns 1.25).
Also no callback at all is fired when the window is moved from one monitor to the other. So to me it appears there is no way for us to detect the contentscale change (we could poll the current value from time to time but i guess it is unlikely anyone would change that setting while a jme application is running)
I also added an action listener that would print the screenpos of the cursor upon click and surprisingly it worked as well meaning whatever current contentscale / size of the window even when chaged at runtime, the value returned when clicking in the top right corner is always the current value of the framebuffersize (thus also the value of the windowsize) even after moving from the 125% contentscale monitor to the 100% contentscale monitor
again this is all only on windows 10

EDIT: tldr i guess on windows 10 the changes to the GLFWMouseInput might not work for people that have their contentscale not set to 100% because although the callback is never fired, the initial poll will return some value != 1.0 and since my quick tests seemed to work without those changes, dividing the returned values by some value != 1.0 would result in wrong values
So it appears on windows 10 this is a value you can poll at the start of your application to adjust font and icon sizes and dont bother with at any other point

EDIT: i just realized, when i start the application with settings.setResolution(1600, 900) then the window initially has the same size on screen regardless of the contentscale currently set. This is expected but when i start the application with contentscale currently set to 125% and i then change it to 100%, the window gets noticably smaller and when i then resize it manually the framebuffersize callback reports values that can be even larger than the resolution of my monitor. so i guess it is not meant to be changed while an application is running

4 Likes

I’m trying to find some glfwWindowHint to enable/disable Retina display. It would be nice to me to save the FPS.

So far I found this one:

#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001

Here is the source.

It was set to true by default.

I suspect it could be turned off easily, with a given setting param. So I do this to the LwjglWindow.

protected void createContext(final AppSettings settings) {
    // ...
    glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, settings.isUseRetinaFrameBuffer() ? GLFW_TRUE : GLFW_FALSE);
    // ...
}

Add this param to AppSettings and set it default value to false.

public final class AppSettings extends HashMap<String, Object> {
    // ...
    static {
        // ... 
        defaults.put("UseRetinaFrameBuffer", false);// MacOS spec
        //  defaults.put("Icons", null);
    }

    /**
     * Determine whether to use full resolution framebuffers on Retina displays.
     *
     * @return whether to use full resolution framebuffers on Retina displays.
     */
    public boolean isUseRetinaFrameBuffer() {
        return getBoolean("UseRetinaFrameBuffer");
    }

    /**
     * Specifies whether to use full resolution framebuffers on Retina displays. This is ignored on other platforms.
     *
     * @param useRetinaFrameBuffer whether to use full resolution framebuffers on Retina displays.
     */
    public void setUseRetinaFrameBuffer(boolean useRetinaFrameBuffer) {
        putBoolean("UseRetinaFrameBuffer", useRetinaFrameBuffer);
    }
}

This is the result.

result#1, set useRetinaFrameBuffer = false

result#2, set useRetinaFrameBuffer = true

Here is the commit.

2 Likes

TLDR:

  • The content scale is wrong at the first frame.
  • The WindowContentScaleCallback is NEVER invoked.
  • I changed GlfwMouseInput to get content scale in real time.

I made more test on useRetinaFrameBuffer and GlfwMouseInput and I find a bug here.

What’s wrong?

When I set GLFW_COCOA_RETINA_FRAMEBUFFER to GLFW_FALSE, it means the framebuffer size should be equal to window size, and content scale should be (1.0, 1.0).

I add log to LwjglWindow#createContext(AppSettings) to see what is the real value.

protected void createContext(final AppSettings settings) {
        // ...
        float[] xScale = new float[1];
        float[] yScale = new float[1];
        glfwGetWindowContentScale(window, xScale, yScale);
        contentScaleX = xScale[0];
        contentScaleY = yScale[0];

        int[] fbSizeX = new int[1];
        int[] fbSizeY = new int[1];
        glfwGetFramebufferSize(window, fbSizeX, fbSizeY);
        LOGGER.log(Level.INFO,"window content scale: ({0}, {1}), frameBuffer size:({2}, {3})",
                new Object[] {contentScaleX, contentScaleY, fbSizeX[0], fbSizeY[0]});
}

and the log

Sep 16, 2021 3:46:02 PM com.jme3.system.lwjgl.LwjglWindow createContext
INFO: window content scale: (2, 2), frameBuffer size:(2,560, 1,440)

NO!! It’s not what I want.

I add more log to GlfwMouseInput

Sep 16, 2021 4:05:39 PM com.jme3.input.lwjgl.GlfwMouseInput onCursorPos
INFO: cursor pos:(401.292, 499.325) -> (803, 441)

The input cursor pos is right, but the result is also incorrect with wrong contentScale.

Then I add click listener to log the realtime content scale and cursor position.

window content scale:(1.00, 1.00), 
cursor pos:(401.2923, 499.3253), 
cursor pos * content scale:(401, 221)

Content scale is (2.0, 2.0) at the first time, it changed to (1.0, 1.0) after a while , while we didn’t get the callback.

When the content scale changed?

I made another test, trying to log the content scale during the game loop, in first 10 frames.

    int frame = 0;

    @Override
    public void simpleUpdate(float tpf) {
        if (frame < 10) {
            frame++;

            Vector2f scale = new Vector2f(1f, 1f);
            JmeContext context = getContext();
            if (context instanceof LwjglWindow) {
                ((LwjglWindow) context).getWindowContentScale(scale);
            }
            log.info("frame:{}, scale:{}", frame, scale);

            if (frame == 2) {// update gui on the 2nd frame
                guiNode.setLocalScale(scale.x, scale.y, 1f);
            } else if (frame == 3) {
                context.restart();// restart the context to see if content scale changed.
            }
        }
    }

The result:

17:40:29.933 [jME3 Main] INFO  f.h.app.CheckerDemo:104 - frame:1, scale:(2.0, 2.0)
17:40:30.079 [jME3 Main] INFO  f.h.app.CheckerDemo:104 - frame:2, scale:(1.0, 1.0)
17:40:30.226 [jME3 Main] INFO  f.h.app.CheckerDemo:104 - frame:3, scale:(1.0, 1.0)
Sep 16, 2021 5:40:30 PM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: Intel Inc.
 * Renderer: Intel(R) Iris(TM) Plus Graphics 645
 * OpenGL Version: 2.1 INTEL-16.4.5
 * GLSL Version: 1.20
 * Profile: Compatibility
17:40:30.320 [jME3 Main] INFO  f.h.app.CheckerDemo:104 - frame:4, scale:(2.0, 2.0)
17:40:30.436 [jME3 Main] INFO  f.h.app.CheckerDemo:104 - frame:5, scale:(1.0, 1.0)
17:40:30.452 [jME3 Main] INFO  f.h.app.CheckerDemo:104 - frame:6, scale:(1.0, 1.0)
17:40:30.467 [jME3 Main] INFO  f.h.app.CheckerDemo:104 - frame:7, scale:(1.0, 1.0)
17:40:30.484 [jME3 Main] INFO  f.h.app.CheckerDemo:104 - frame:8, scale:(1.0, 1.0)
17:40:30.501 [jME3 Main] INFO  f.h.app.CheckerDemo:104 - frame:9, scale:(1.0, 1.0)
17:40:30.513 [jME3 Main] INFO  f.h.app.CheckerDemo:104 - frame:10, scale:(1.0, 1.0)

The content scale is wrong at the 1st frame, after that it’s value was changed.

The application didn’t get any callback about it.

How to fix?

To fix this bug.

    private void onCursorPos(final long window, final double xpos, final double ypos) {
        // get content scale in real time
        float[] xScale = new float[1];
        float[] yScale = new float[1];
        glfwGetWindowContentScale(window, xScale, yScale);

        int xDelta;
        int yDelta;
        int x = (int) Math.round(xpos * xScale[0]);
        int y = (int) Math.round((currentHeight - ypos) * yScale[0]);

        xDelta = x - mouseX;
        yDelta = y - mouseY;
        mouseX = x;
        mouseY = y;

        if (xDelta != 0 || yDelta != 0) {
            final MouseMotionEvent mouseMotionEvent = new MouseMotionEvent(x, y, xDelta, yDelta, mouseWheel, 0);
            mouseMotionEvent.setTime(getInputTimeNanos());
            mouseMotionEvents.add(mouseMotionEvent);
        }
    }
1 Like

Another day. More tests for GLFW FrameBufferSize.

TLDR

  • The initial value of glfwGetFramebufferSize is always scaled in Retina Display, no matter the GLFW_COCOA_RETINA_FRAMEBUFFER is set to GLFW_TRUE or GLFW_FALSE.
  • From the 2nd frame after LwjglWindow started, glfwGetFramebufferSize returns the correct value.
  • This value change does not affect to GLFWFrameBufferSizeCallback. The callback only works when you resize the window.

Test Case

I tried to move the window, resize the window, restart the context, enable/disable the useRetinaFrameBuffer. Just to see what would happen.

import com.jme3.app.SimpleApplication;
import com.jme3.math.ColorRGBA;
import com.jme3.system.AppSettings;
import com.jme3.system.lwjgl.LwjglWindow;
import lombok.extern.slf4j.Slf4j;
import org.lwjgl.glfw.GLFW;

@Slf4j
public class TestRestartContext extends SimpleApplication {

    public static void main(String[] args) {
        AppSettings settings = new AppSettings(true);
        settings.setResolution(1280, 720);
        settings.setUseRetinaFrameBuffer(true);// change it
        settings.setResizable(true);

        TestRestartContext app = new TestRestartContext();
        app.setSettings(settings);
        app.setShowSettings(false);
        app.start();
    }

    @Override
    public void simpleInitApp() {
        viewPort.setBackgroundColor(ColorRGBA.LightGray);
        flyCam.setDragToRotate(true);
    }

    int frame = 0;
    @Override
    public void simpleUpdate(float tpf) {
        if (frame < 10) {
            frame++;
            int w = -1;
            int h = -1;
            if (context instanceof LwjglWindow) {
                LwjglWindow lwjgl = (LwjglWindow) context;

                long window = lwjgl.getWindowHandle();

                int[] width = new int[1];
                int[] height = new int[1];
                GLFW.glfwGetFramebufferSize(window, width, height);

                w = width[0];
                h = height[0];
                log.info("frame#{}: cam res={}x{}, fbSize={}x{}", frame, cam.getWidth(), cam.getHeight(), w, h);
            }

//            if (frame == 3) {
//                if (h != -1 && w != -1) {
//                    reshape(w, h);
//                }
//            }

            if (frame == 5) {
                context.restart();
            }

//            if (frame == 7) {
//                if (h != -1 && w != -1) {
//                    reshape(w, h);
//                }
//            }
        }
    }
}

screenshot before frame#5

screenshot after frame#5

this is the log

09:29:28.795 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#1: cam res=1280x720, fbSize=2560x1440
09:29:28.914 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#2: cam res=1280x720, fbSize=2560x1440
09:29:29.144 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#3: cam res=1280x720, fbSize=2560x1440
09:29:29.149 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#4: cam res=1280x720, fbSize=2560x1440
09:29:29.165 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#5: cam res=1280x720, fbSize=2560x1440
Sep 17, 2021 9:29:29 AM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: Intel Inc.
 * Renderer: Intel(R) Iris(TM) Plus Graphics 645
 * OpenGL Version: 2.1 INTEL-16.4.5
 * GLSL Version: 1.20
 * Profile: Compatibility
09:29:29.271 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#6: cam res=1280x720, fbSize=2560x1440
09:29:29.388 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#7: cam res=1280x720, fbSize=2560x1440
09:29:29.411 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#8: cam res=1280x720, fbSize=2560x1440
09:29:29.421 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#9: cam res=1280x720, fbSize=2560x1440
09:29:29.432 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#10: cam res=1280x720, fbSize=2560x1440

When useRetinaFrameBuffer is true, restart context leads to a wrong result.
The content scale is (2.0, 2.0), the glfwFrameBufferSize is 2560x1440, but camera resolution is still 1280x720.
Mouse left click at window position (100, 100) would get mouse input (200, 200) because of the content scale (2.0, 2.0);

Move, Resize

Move the window after context restarted, nothing changed.

Move the window before context restarted, the left bottom corner is doubled.

Resize the window a little, the application received GLFWFrameBufferSizeCallback. The screen is right now.

Turn off useRetinaFrameBuffer

Nearly the same result, but move or resize the window does not change anything.

content scale and frame buffer size is wrong at the 1st frame after context started.

09:55:54.649 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#1: cam res=1280x720, fbSize=2560x1440
09:55:54.762 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#2: cam res=1280x720, fbSize=1280x720
09:55:54.931 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#3: cam res=1280x720, fbSize=1280x720
09:55:54.950 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#4: cam res=1280x720, fbSize=1280x720
09:55:54.967 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#5: cam res=1280x720, fbSize=1280x720
Sep 17, 2021 9:55:55 AM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: Intel Inc.
 * Renderer: Intel(R) Iris(TM) Plus Graphics 645
 * OpenGL Version: 2.1 INTEL-16.4.5
 * GLSL Version: 1.20
 * Profile: Compatibility
09:55:55.031 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#6: cam res=1280x720, fbSize=2560x1440
09:55:55.109 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#7: cam res=1280x720, fbSize=1280x720
09:55:55.122 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#8: cam res=1280x720, fbSize=1280x720
09:55:55.138 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#9: cam res=1280x720, fbSize=1280x720
09:55:55.155 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#10: cam res=1280x720, fbSize=1280x720

An idea to fix it.

As I see, the correct content scale and frame buffer size can be get from the 2nd frame, how about just invoke SystemListener#reshape(int width, int height) at that point?

    int frame = 0;
    @Override
    public void simpleUpdate(float tpf) {
        if (frame < 10) {
            frame++;
            int w = -1;
            int h = -1;
            if (context instanceof LwjglWindow) {
                LwjglWindow lwjgl = (LwjglWindow) context;

                long window = lwjgl.getWindowHandle();

                int[] width = new int[1];
                int[] height = new int[1];
                GLFW.glfwGetFramebufferSize(window, width, height);

                w = width[0];
                h = height[0];
                log.info("frame#{}: cam res={}x{}, fbSize={}x{}", frame, cam.getWidth(), cam.getHeight(), w, h);
            }

            if (frame == 3) {
                if (h != -1 && w != -1) {
                    reshape(w, h);
                }
            }

            if (frame == 5) {
                context.restart();
            }

//            if (frame == 7) {
//                if (h != -1 && w != -1) {
//                    reshape(w, h);
//                }
//            }
        }
    }
}

It works perfect for me.

May I just do it in LwjglWindow#runLoop() ?

After this fix, the result looks better from frame#2, and all the test case above works fine now.

10:20:24.634 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#1: cam res=1280x720, fbSize=2560x1440
10:20:24.752 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#2: cam res=2560x1440, fbSize=2560x1440
10:20:24.936 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#3: cam res=2560x1440, fbSize=2560x1440
10:20:24.942 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#4: cam res=2560x1440, fbSize=2560x1440
10:20:24.957 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#5: cam res=2560x1440, fbSize=2560x1440
Sep 17, 2021 10:20:25 AM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: Intel Inc.
 * Renderer: Intel(R) Iris(TM) Plus Graphics 645
 * OpenGL Version: 2.1 INTEL-16.4.5
 * GLSL Version: 1.20
 * Profile: Compatibility
10:20:25.055 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#6: cam res=2560x1440, fbSize=2560x1440
10:20:25.150 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#7: cam res=2560x1440, fbSize=2560x1440
10:20:25.164 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#8: cam res=2560x1440, fbSize=2560x1440
10:20:25.188 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#9: cam res=2560x1440, fbSize=2560x1440
10:20:25.197 [jME3 Main] INFO  f.h.a.TestRestartContext:49 - frame#10: cam res=2560x1440, fbSize=2560x1440

Pull Request

Here are the PRs I made, trying to fix issue #893.

@pspeed @sgold @tonihele Sir, please check my pull request, thanks. :grinning_face_with_smiling_eyes:

1 Like

Will check it at some point. Thanks for your work. It would be awesome to get this finally fixed for all OSes. Support those HiDPI everywhere.

1 Like

Since I don’t have hands-on access to a macOS system, I’m delighted to have you working this issue.

I’m not very familiar with LWJGL and Retina. However, it sounds to me like you’re trying to work around bugs and/or quirks in LWJGL v3.2.3. That’s fine, but keep in mind that someday v3.3 will be released, and JME will eventually adopt it. LWJGL v3.3 may fix the issue and/or invalidate any workarounds.

3 Likes

Is it possible to use the alpha version of LWJGL 3.3. with JME?

1 Like

It should be fairly easy if you know how to build the Engine from source.

I made tests to the latest glfw, found the same bug.
I think LWJGL 3.3 may not fix this bug for now.

For anyone have interests about the test to glfw.

Platform

  • GLFW version: glfw-3.3.4.bin.MACOS
  • Compiler: Apple clang version 12.0.0 (clang-1200.0.32.27)
  • Target: x86_64-apple-darwin20.5.0
  • MacOS version: 11.4
gcc main.c -Wall \
 -I $GLFW_HOME/include \
 -L $GLFW_HOME/lib-x86_64 \
 -l glfw.3 \
 -o main.bin \
 -rpath ./

$GLFW_HOME is where I put glfw-3.3.4.bin.MACOS

Test Source Code

main.c

#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void errorCallback(int error, const char* description) {
    fprintf(stderr, "Error: %s\n", description);
}

void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
        glfwSetWindowShouldClose(window, GLFW_TRUE);
    }
}

void framebufferSizeCallback(GLFWwindow* window, int width, int height) {
    printf("callback fbSize=%dx%d\n", width, height);
}

void printFrameBufferSize(GLFWwindow* window, int frame) {
    int w, h;
    float xscale, yscale;
    glfwGetFramebufferSize(window, &w, &h);
    glfwGetWindowContentScale(window, &xscale, &yscale);
    printf("frame#%d, fbSize=%dx%d, scale=%.2fx%.2f\n", frame, w, h, xscale, yscale);
}

int main(int argc, char const *argv[]) {
    int frame = -2;// two frame before loops
    int useRetinaFrameBuffer = GLFW_FALSE;
    int isPollEventBeforeLoop = GLFW_FALSE;

    for (int i = 0; i < argc; i++) {
        if (strncmp("retina", argv[i], 6) == 0) {
            useRetinaFrameBuffer = GLFW_TRUE;
        }
        if (strncmp("poll", argv[i], 4) == 0) {
            isPollEventBeforeLoop = GLFW_TRUE;
        }
    }

    glfwSetErrorCallback(errorCallback);

    if (!glfwInit()) {
        exit(-1);
    }

    // hint
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
#endif
    glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, useRetinaFrameBuffer);

    GLFWwindow* window = glfwCreateWindow(640, 400, "Test FrameBuffer Size", NULL, NULL);
    if (!window) {
        glfwTerminate();
        exit(-1);
    }

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);
    glfwSetKeyCallback(window, keyCallback);
    glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);

    // loop
    printFrameBufferSize(window, frame++);

    if (isPollEventBeforeLoop) {
        glfwPollEvents();// <------- this is the point which changed glfwGetFramebufferSize result
    }

    printFrameBufferSize(window, frame++);

    printf("\n");

    while (!glfwWindowShouldClose(window)) {
        if (frame < 10) {
            printFrameBufferSize(window, frame++);
        } else {
            glfwSetWindowShouldClose(window, GLFW_TRUE);// close it
        }

        glfwSwapBuffers(window);
        glfwPollEvents();// <------- this is the point which changed glfwGetFramebufferSize result
    }

    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

The result

Test CASE 1

use retina display = false
poll events before loop = false

./main.bin
frame#-2, fbSize=1280x800, scale=2.00x2.00
frame#-1, fbSize=1280x800, scale=2.00x2.00

frame#0, fbSize=1280x800, scale=2.00x2.00
frame#1, fbSize=640x400, scale=1.00x1.00
frame#2, fbSize=640x400, scale=1.00x1.00
frame#3, fbSize=640x400, scale=1.00x1.00
frame#4, fbSize=640x400, scale=1.00x1.00
frame#5, fbSize=640x400, scale=1.00x1.00
frame#6, fbSize=640x400, scale=1.00x1.00
frame#7, fbSize=640x400, scale=1.00x1.00
frame#8, fbSize=640x400, scale=1.00x1.00
frame#9, fbSize=640x400, scale=1.00x1.00

Test CASE 2

use retina display = false
poll events before loop = true

./main.bin poll
frame#-2, fbSize=1280x800, scale=2.00x2.00
frame#-1, fbSize=640x400, scale=1.00x1.00

frame#0, fbSize=640x400, scale=1.00x1.00
frame#1, fbSize=640x400, scale=1.00x1.00
frame#2, fbSize=640x400, scale=1.00x1.00
frame#3, fbSize=640x400, scale=1.00x1.00
frame#4, fbSize=640x400, scale=1.00x1.00
frame#5, fbSize=640x400, scale=1.00x1.00
frame#6, fbSize=640x400, scale=1.00x1.00
frame#7, fbSize=640x400, scale=1.00x1.00
frame#8, fbSize=640x400, scale=1.00x1.00
frame#9, fbSize=640x400, scale=1.00x1.00

Test CASE 3

use retina display = true
poll events before loop = false

./main.bin retina
frame#-2, fbSize=1280x800, scale=2.00x2.00
frame#-1, fbSize=1280x800, scale=2.00x2.00

frame#0, fbSize=1280x800, scale=2.00x2.00
frame#1, fbSize=1280x800, scale=2.00x2.00
frame#2, fbSize=1280x800, scale=2.00x2.00
frame#3, fbSize=1280x800, scale=2.00x2.00
frame#4, fbSize=1280x800, scale=2.00x2.00
frame#5, fbSize=1280x800, scale=2.00x2.00
frame#6, fbSize=1280x800, scale=2.00x2.00
frame#7, fbSize=1280x800, scale=2.00x2.00
frame#8, fbSize=1280x800, scale=2.00x2.00
frame#9, fbSize=1280x800, scale=2.00x2.00

Test CASE 4

use retina display = true
poll events before loop = true

./main.bin retina poll
frame#-2, fbSize=1280x800, scale=2.00x2.00
frame#-1, fbSize=1280x800, scale=2.00x2.00

frame#0, fbSize=1280x800, scale=2.00x2.00
frame#1, fbSize=1280x800, scale=2.00x2.00
frame#2, fbSize=1280x800, scale=2.00x2.00
frame#3, fbSize=1280x800, scale=2.00x2.00
frame#4, fbSize=1280x800, scale=2.00x2.00
frame#5, fbSize=1280x800, scale=2.00x2.00
frame#6, fbSize=1280x800, scale=2.00x2.00
frame#7, fbSize=1280x800, scale=2.00x2.00
frame#8, fbSize=1280x800, scale=2.00x2.00
frame#9, fbSize=1280x800, scale=2.00x2.00

TLDR

Test initial result of glfwGetFrameBufferSize and glfwGetWindowContentScale is incorrect on glfw 3.3.4 MacOS, when I run on retina display but set GLFW_COCOA_RETINA_FRAMEBUFFER to GLFW_FALSE.

glfwPollEvents() will correct that result, but framebufferSizeCallback is never invoked.

3 Likes

In the past (before moving to gradle), I did build the sdk/engine from source (just load it on netbeans and hit build). I guess now it’s more complicated than that?

Then, what I hoped to hear is “you can switch with whatever LWJGL you like with this gradle trickery”.

However, as you suggest, I’ll take a look at the build.

1 Like

In this case, the “Gradle trickery” consists of editing “jme3-lwjgl3/build.gradle” to change

def lwjglVersion = '3.2.3'

to

def lwjglVersion = '3.3.0-SNAPSHOT'
repositories {
    maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}

and performing a clean build.

The details of building from source will depend on your IDE. From Bash or PowerShell, it’s simply:

$ ./gradlew clean build
2 Likes

@tonihele please check this PR. let’s solve this issue before 3.5.0.

3 Likes

I am resurrecting this thread to ask why we need to wait two frames, can’t we just call glfwPollEvents twice during the initialization? @yan

1 Like

Mainly because I’m not too sure if it will trigger any callbacks.
I don’t know if there will be side effects, so I want just keep it goes like it was in old ways.

3 Likes