Switching to LWJGL 3

I have tried to switch JMonkeyEngine to LWJGL 3. I have only changed the Maven dependency to

<dependency>
		<groupId>org.jmonkeyengine</groupId>
		<artifactId>jme3-lwjgl3</artifactId>
		<version>3.2.1-stable</version>
</dependency>

First I got an error that required to add -XstartOnFirstThread to VM options.

After solving that I get the following result in the screen (cropped). The original scene is shown only in the lower left quarter of the view and the rest of the view is flickering in black/white lines. I suspect this might be caused by running on Retina display on macOS. However I do not know how to solve this.

58

Thank you for an advice.

This will not help you that much… But this is a known issue unfortunately:
https://github.com/jMonkeyEngine/jmonkeyengine/issues/893

1 Like

It doesn’t sound too difficult to fix. But I for one lack hardware to test, maybe skills too :slight_smile: I hope someone can tackle that finally.

1 Like

Thank you. At least I know not to search for this issue in my code.

1 Like


Same issue with MacOS retina screen.

Does it work if you resize the window? That has been fixed, or should have been. Only the initial status remains like this. I don’t have the hardware to test.

Oh! It looks better after I resize the window. But the GUI still have some problem.

1 Like

That looks like Lemur? Dunno is that a separate issue. The thing is that this is not all that difficult to fix technically, the initial state you have. https://github.com/jMonkeyEngine/jmonkeyengine/issues/893. Just little bit of decisions needed, and a hardware to test.

If it’s Lemur, it’s just going to put the things where you tell it. Even the methods it provides for centering things in the GUI will use the current Camera values for width/height.

…so as long as those are being reported correctly then this seems like a “user code” issue.

It’s hard to tell how wired the situation is, I try to explain what I saw.

Test: Cursor position.

import com.jme3.input.event.MouseButtonEvent;
import com.jme3.system.AppSettings;
import com.simsilica.lemur.demo.BasicDemo;
import com.simsilica.lemur.event.DefaultRawInputListener;

public class LemurBasicDemo {
    public static void main(String[] args) {

        AppSettings settings = new AppSettings(true);
        settings.setResolution(1280, 720);
        settings.setResizable(true);

        BasicDemo app = new BasicDemo() {
            @Override
            public void simpleInitApp() {
                super.simpleInitApp();

                inputManager.addRawInputListener(new DefaultRawInputListener() {
                    @Override
                    public void onMouseButtonEvent(MouseButtonEvent evt) {
                        System.out.printf("The cursor click position:%s\n", inputManager.getCursorPosition());
                    }
                });
            }
        };
        app.setSettings(settings);
        app.setShowSettings(false);
        app.start();
    }

}

The cursor click position: (69.0, 658.0)

Test: guiNode.scale(2f);

I hardcode the guiNode.scale to 2.0 to suite retina screen. Then I found I just can’t get the correct gui position.

I can no more click the checkbox ‘Show Stats’.

I have to offset the cursor for a distance to drag the panel.

import com.jme3.input.event.MouseButtonEvent;
import com.jme3.system.AppSettings;
import com.simsilica.lemur.demo.BasicDemo;
import com.simsilica.lemur.event.DefaultRawInputListener;

public class LemurBasicDemo {
    public static void main(String[] args) {

        AppSettings settings = new AppSettings(true);
        settings.setResolution(1280, 720);
        settings.setResizable(true);

        BasicDemo app = new BasicDemo() {
            @Override
            public void simpleInitApp() {
                super.simpleInitApp();
                guiNode.scale(2f);//hard code to suite the retina screen

                inputManager.addRawInputListener(new DefaultRawInputListener() {
                    @Override
                    public void onMouseButtonEvent(MouseButtonEvent evt) {
                        System.out.printf("The cursor click position:%s\n", inputManager.getCursorPosition());
                    }
                });
            }
        };
        app.setSettings(settings);
        app.setShowSettings(false);
        app.start();
    }

}

The cursor click position:(828.0, 390.0)

Log the cursor coordinates that JME is returning… I suspect they will be wrong.

https://javadoc.jmonkeyengine.org/v3.4.0-stable/com/jme3/input/InputManager.html#getCursorPosition--

Edit: nevermind, I see that you do.

But Lemur is doing nothing fancy here. It’s just asking JME for the cursor position just like you are. It’s possible that the GUI positions and screen positions don’t align but that would be based on the camera settings.

Lemur isn’t really doing anything magic here, I think. I feel like JME must be reporting something incorrectly.

Edit 2: note that in my JME apps, I rescale my GUIs all the time without issue. The only difference is that I rarely scale the GUI node itself and scale a child instead that I use as root. But it really shouldn’t matter.

Made another test.

I suspect it is the input cursor is not right.

The guiViewPort resolution is doubled, while the input cursor not. When use a Ray(cursor.x, cursor.y, -1) will get false results.

Here is the test code.

import com.jme3.app.FlyCamAppState;
import com.jme3.app.SimpleApplication;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.material.Material;
import com.jme3.material.Materials;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Quad;
import com.jme3.system.AppSettings;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.event.*;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class CheckerDemo extends SimpleApplication {
    static int WIDTH = 1280;
    static int HEIGHT = 720;
    static int SIZE = 80;// (1280, 720) = 80 * (16, 9)

    public static void main(String[] args) {

        AppSettings settings = new AppSettings(true);
        settings.setResolution(WIDTH, HEIGHT);
        settings.setResizable(true);

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

    @Override
    public void simpleInitApp() {
        GuiGlobals.initialize(this);
        // stateManager.getState(MouseAppState.class);
        stateManager.detach(stateManager.getState(FlyCamAppState.class));

        // guiNode.scale(2f);//hard code to suite the retina screen

        // create 16*9 quads as a checkerboard.
        Mesh mesh = new Quad(SIZE, SIZE);
        for (int y=0; y<9; y++) {
            for (int x=0; x<16; x++) {

                ColorRGBA color;
                if ((x + y) % 2 == 0) {
                    color = new ColorRGBA(1f - x / 16f, y / 9f, 1f, 1f);
                } else {
                    color = new ColorRGBA(x / 16f, 1f - y / 9f, 1f, 1f);
                }

                Material mat = new Material(assetManager, Materials.UNSHADED);
                mat.setColor("Color", color);

                Geometry geom = new Geometry("#("+x+","+y+")", mesh);
                geom.setMaterial(mat);
                geom.move(x * SIZE * 2f, y * SIZE * 2f, 0);
                geom.scale(2f);
                guiNode.attachChild(geom);

                MouseEventControl.addListenersToSpatial(geom, new DefaultMouseListener() {
                    @Override
                    protected void click( MouseButtonEvent event, Spatial target, Spatial capture ) {
                        Vector2f cursor = inputManager.getCursorPosition();
                        System.out.printf("geom:%s, cursor:%s, cam:%s\n", target.getName(), cursor, guiViewPort.getCamera());
                    }

                    @Override
                    public void mouseEntered(MouseMotionEvent event, Spatial target, Spatial capture ) {
                        Material m = ((Geometry)target).getMaterial();
                        m.setColor("Color", ColorRGBA.Yellow);
                    }

                    @Override
                    public void mouseExited( MouseMotionEvent event, Spatial target, Spatial capture ) {
                        Material m = ((Geometry)target).getMaterial();
                        m.setColor("Color", color);
                    }
                });

            }
        }
    }

}

Console output

geom:#(6,2), cursor:(1111.0, 346.0), cam:Camera[location=(0.0, 0.0, 0.0)
, direction=(0.0, 0.0, 1.0)
res=2560x1440, parallel=true
near=1.0, far=2.0]

I turned PickEventSession.debug on, here is the lemur debug log:

16:10:49.972 [jME3 Main] DEBUG c.s.l.e.PickEventSession:156 - cursorMoved(1111, 346, scroll=0) capture:null
16:10:49.973 [jME3 Main] DEBUG c.s.l.e.PickEventSession:156 - getPickRay(RootEntry[viewport=com.jme3.renderer.ViewPort@4b86805d, root=Gui Node (Node), layer=gui], (1111.0, 346.0))
16:10:49.973 [jME3 Main] DEBUG c.s.l.e.PickEventSession:156 - Creating GuiBucket ray.
16:10:49.973 [jME3 Main] DEBUG c.s.l.e.PickEventSession:156 - Picking against:RootEntry[viewport=com.jme3.renderer.ViewPort@4b86805d, root=Gui Node (Node), layer=gui] with:Ray [Origin: (1111.0, 346.0, 1.0), Direction: (0.0, 0.0, -1.0)]
16:10:49.973 [jME3 Main] DEBUG c.s.l.e.PickEventSession:156 - Collision geometry:#(6,2) (Geometry)
16:10:49.973 [jME3 Main] DEBUG c.s.l.e.PickEventSession:156 - Hit:#(6,2) (Geometry)

Then I make it into rootNode.

cursor

geom:#(4,3), cursor:(1003.0, 524.0)

I think it’s time to give up MacOS. :face_with_symbols_over_mouth:

Don’t give up :smiley: It is problematic. But for the benefit of whole humanity, lets fix these bugs from jME. This resolution gimmick is not limited only to macs.

2 Likes

Could be that the cursor position should be scaled with glfwGetWindowContentScale. Following this discussion: https://github.com/glfw/glfw/issues/845. We don’t do this currently.

1 Like

Another try.

                    @Override
                    protected void click( MouseButtonEvent event, Spatial target, Spatial capture ) {
                        Vector2f cursor = inputManager.getCursorPosition();
                        System.out.printf("geom:%s, cursor:%s\n", target.getName(), cursor);

                        // get window handle
                        LwjglWindow context = (LwjglWindow) getContext();
                        long window = context.getWindowHandle();
                        // get window content scale
                        float[] xScale = new float[1];
                        float[] yScale = new float[1];
                        GLFW.glfwGetWindowContentScale(window, xScale, yScale);
                        // get cursor pos
                        double[] xPos = new double[1];
                        double[] yPos = new double[1];
                        GLFW.glfwGetCursorPos(window, xPos, yPos);
                        // real pos = pos * scale
                        double x = xPos[0] * xScale[0];
                        double y = yPos[0] * yScale[0];
                        System.out.printf("window content scale:(%.2f, %.2f), cursor pos:(%.4f, %.4f), content pos:(%.2f, %.2f)\n", xScale[0], yScale[0], xPos[0], yPos[0], x, y);
                    }

lt looks more reasonable.

geom:#(11,6), cursor:(777.0, 380.0)
window content scale:(2.00, 2.00), cursor pos:(777.4167, 340.1673), content pos:(1554.83, 680.33)
geom:#(13,7), cursor:(899.0, 423.0)
window content scale:(2.00, 2.00), cursor pos:(899.4674, 297.3557), content pos:(1798.93, 594.71)

How familiar are you with the jME code base? We could tackle all these easily. PRs to jME.

1 Like

I’d like to give it a try.
Just after my son sleep.:thinking:

2 Likes

It seems OK to me, but I think I need to make more test to it.

2 Likes

i played around with glfwGetWindowContentScale a while ago (never did any test on mac though, that was not why i played around with it) but i want to mention that on windows 10 when you change the content scale to 125%, glfwGetWindowContentScale will actually report the 1.25 although in that case you might not want to scale the cursor position (havent read the whole thread so i dont know the details)
i initially played around with it exactly for that content scale setting to adjust the font size in game according to what the user set in their windows 10 settings (i assume it is not only windows 10, but it is the only os i played around with it on)

2 Likes