diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 3e6b4477aa..41aa552c70 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -47,7 +47,7 @@ junit4 = "junit:junit:4.13.2"
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" }
junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" }
lwjgl2 = "org.jmonkeyengine:lwjgl:2.9.5"
-lwjgl3-awt = "org.jmonkeyengine:lwjgl3-awt:0.2.4"
+lwjgl3-awt = "org.lwjglx:lwjgl3-awt:0.2.5"
lwjgl3-base = { module = "org.lwjgl:lwjgl", version.ref = "lwjgl3" }
lwjgl3-glfw = { module = "org.lwjgl:lwjgl-glfw", version.ref = "lwjgl3" }
diff --git a/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java b/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java
index 18aa0183ca..eb9e71acce 100644
--- a/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java
+++ b/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java
@@ -35,6 +35,8 @@
import com.jme3.app.SimpleApplication;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
+import com.jme3.system.JmeSystem;
+import com.jme3.system.Platform;
import com.jme3.util.JmeFormatter;
import java.awt.BorderLayout;
import java.awt.Canvas;
@@ -60,6 +62,7 @@ public class TestCanvas {
private static Container canvasPanel1, canvasPanel2;
private static Container currentPanel;
private static JTabbedPane tabbedPane;
+ private static boolean platformX11 = false;
private static final String appClass = "jme3test.post.TestRenderToTexture";
private static void createTabs(){
@@ -170,7 +173,7 @@ public void actionPerformed(ActionEvent e){
public void actionPerformed(ActionEvent e) {
currentPanel.remove(canvas);
app.stop(true);
-
+
createCanvas(appClass);
currentPanel.add(canvas, BorderLayout.CENTER);
frame.pack();
@@ -187,6 +190,10 @@ public void actionPerformed(ActionEvent ae) {
app.stop();
}
});
+
+ if (JmeSystem.getPlatform().getOs() == Platform.Os.Linux) {
+ frame.setTitle("Test - Platform " + (platformX11 ? "X11" : "XWayland"));
+ }
}
private static void createFrame(){
@@ -207,9 +214,9 @@ public void windowClosed(WindowEvent e) {
public static void createCanvas(String appClass){
AppSettings settings = new AppSettings(true);
- // Note: Only for Linux and Wayland platforms, forces you to
- // use XWayland (x11) with awt.
- settings.setX11PlatformPreferred(true);
+ // Note: Only for Linux and Wayland platforms, select the
+ // XWayland or x11 platform (if possible).
+ settings.setX11PlatformPreferred(platformX11);
settings.setRenderer(AppSettings.LWJGL_OPENGL32);
settings.setWidth(640);
settings.setHeight(480);
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java
index b6126a5b44..354679c928 100644
--- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java
@@ -72,7 +72,6 @@
import org.lwjgl.opengl.awt.GLData;
import org.lwjgl.system.Configuration;
-import org.lwjgl.system.Platform;
import static org.lwjgl.system.MemoryUtil.*;
import static com.jme3.system.lwjglx.LwjglxDefaultGLPlatform.*;
@@ -185,10 +184,10 @@ private class LwjglAWTGLCanvas extends Canvas {
/**
* Information object used to create the OpenGL context.
*/
- private GLData data;
+ private final GLData data;
/** Effective data to initialize the context. */
- private GLData effective;
+ private final GLData effective;
/**
* Constructor of the LwjglAWTGLCanva class where objects are
@@ -200,14 +199,35 @@ public LwjglAWTGLCanvas(GLData data) {
this.effective = new GLData();
this.context = NULL;
this.data = data;
+ }
+ /**
+ * Create the platform according to the operating system and user
+ * preferences.
+ *
+ * @param settings Backend configurations
+ */
+ public void createPlatform(AppSettings settings) {
try {
- platformCanvas = createLwjglxGLPlatform();
+ platformCanvas = createLwjglxGLPlatform(settings);
} catch (UnsupportedOperationException e) {
listener.handleError(e.getLocalizedMessage(), e);
}
}
+ /**
+ * Returns information about the controllers (names) that are being
+ * used.
+ *
+ * @return String
+ */
+ public String getVideoDriver() {
+ if (platformCanvas == null) {
+ return "Unknown NULL";
+ }
+ return platformCanvas.getVideoDriver();
+ }
+
/**
* (non-Javadoc)
* @see java.awt.Component#addComponentListener(java.awt.event.ComponentListener)
@@ -464,33 +484,8 @@ protected String getCurrentVideoDriver() {
buffer.append("AWT|Swing (LWJGLX) GLv")
.append(canvas.data.majorVersion)
.append('.')
- .append(canvas.data.minorVersion);
-
- String driver = JmeSystem.isWaylandSession() ? "(XWayland|X11) GLX" : "X11 GLX";
-
- Platform platform = Platform.get();
- if (null == platform) {
- buffer.append(" Unknown NULL");
- } else {
- switch (platform) {
- case FREEBSD:
- buffer.append(" FreeBSD ")
- .append(driver);
- break;
- case LINUX:
- buffer.append(" Linux ")
- .append(driver);
- break;
- case MACOSX:
- buffer.append(" MacOSX Cocoa NSGL");
- break;
- case WINDOWS:
- buffer.append(" Win32 WGL");
- break;
- default:
- break;
- }
- }
+ .append(canvas.data.minorVersion)
+ .append(' ').append(canvas.getVideoDriver());
return String.valueOf(buffer);
}
@@ -539,11 +534,13 @@ public void run() {
renderer.cleanup();
}
+ canvas.lock();
canvas.releaseContext();
canvas.deleteContext();
canvas.doDisposeCanvas();
canvas.context = NULL;
} finally {
+ canvas.unlock();
renderable.set(false);
lock.notifyAll();
}
@@ -705,19 +702,12 @@ protected void destroyContext() {
*/
@Override
protected void createContext(AppSettings settings) {
- boolean linux = Platform.get() == Platform.LINUX
- || Platform.get() == Platform.FREEBSD;
- if (!settings.isX11PlatformPreferred() && linux && JmeSystem.isWaylandSession()) {
- LOGGER.log(Level.WARNING, "LWJGLX and AWT/Swing only work with X11, so XWayland will be used for GLX.");
- }
-
- // HACK: For LWJGLX to work in Wyland, it is necessary to use GLX via
- // XWayland, so LWJGL must be forced to load GLX as a native API.
- // This is because LWJGLX does not provide an EGL context.
- if (linux && JmeSystem.isWaylandSession()) {
+ if (settings.isX11PlatformPreferred() && JmeSystem.isWaylandSession()) {
Configuration.OPENGL_CONTEXT_API.set("native");
+ LOGGER.log(Level.INFO, "The use of GLX is forced through XWayland (X11).");
}
+ canvas.createPlatform(settings);
RENDER_CONFIGS.computeIfAbsent(settings.getRenderer(), (t) -> {
return (data) -> {
data.majorVersion = 2;
@@ -761,7 +751,12 @@ protected void createContext(AppSettings settings) {
allowSwapBuffers = settings.isSwapBuffers();
canvas.createContext();
- canvas.makeCurrent();
+ try {
+ canvas.lock();
+ canvas.makeCurrent();
+ } finally {
+ canvas.unlock();
+ }
SwingUtilities.invokeLater(() -> {
canvas.validate();
@@ -1070,7 +1065,8 @@ public void setSettings(AppSettings settings) {
StringBuilder buffer = new StringBuilder();
buffer.append("LWJGLX is not compatible with ANGLE/SDL or GLES, as it only supports the following:")
.append('\n').append(" * WGL | Windows")
- .append('\n').append(" * GLX | Linux (X11/XWayland)")
+ .append('\n').append(" * GLX | Linux (X11)")
+ .append('\n').append(" * EGL | Linux (XWayland)")
.append('\n').append(" * CGL | MacOsX")
.append('\n').append(" * Therefore, version ")
.append(AppSettings.LWJGL_OPENGL32)
@@ -1079,6 +1075,16 @@ public void setSettings(AppSettings settings) {
LOGGER.log(Level.WARNING, String.valueOf(buffer));
settings.setRenderer(AppSettings.LWJGL_OPENGL32);
}
+
+ if (isGLInitAPI() && JmeSystem.isWaylandSession()
+ && (getSettings().isX11PlatformPreferred() != settings.isX11PlatformPreferred())) {
+ LOGGER.log(Level.WARNING, " Platform Preferred: \n"
+ + " * It is not possible to switch platforms at runtime (from GLX to EGL or vice versa)");
+
+ settings.setX11PlatformPreferred(
+ getSettings().isX11PlatformPreferred()
+ );
+ }
super.setSettings(settings);
}
}
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxDefaultGLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxDefaultGLPlatform.java
index aacda06818..6fa776b8be 100644
--- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxDefaultGLPlatform.java
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxDefaultGLPlatform.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2023 jMonkeyEngine
+ * Copyright (c) 2009-2026 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,12 @@
*/
package com.jme3.system.lwjglx;
-import org.lwjgl.system.Platform;
+import com.jme3.system.AppSettings;
+import com.jme3.system.JmeSystem;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.lwjgl.system.Platform;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.system.Platform.*;
@@ -42,6 +46,11 @@
*/
public final class LwjglxDefaultGLPlatform {
+ /**
+ * A flag indicating that the GL API has been initialized or loaded.
+ */
+ private static final AtomicBoolean CHECK_GL_INITAPI = new AtomicBoolean(false);
+
/**
* Detects if you are in a Wayland session.
*
@@ -61,6 +70,18 @@ public static boolean isWayland() {
return false;
}
+ /**
+ * Returns the value of the indicator signaling the load status of the GL
+ * API.
+ *
+ * @see #CHECK_GL_INITAPI
+ *
+ * @return boolean
+ */
+ public static boolean isGLInitAPI() {
+ return CHECK_GL_INITAPI.get();
+ }
+
/**
* Returns the pointer to a {@code Display*} that uses X11.
*
@@ -80,17 +101,23 @@ public static long getX11Display(LwjglxGLPlatform platform) {
/**
* Returns a drawing platform based on the platform it is running on.
*
+ * @param settings AppSettings
+ *
* @return LwjglxGLPlatform
+ *
* @throws UnsupportedOperationException throws exception if platform is not
- * supported
+ * supported
*/
- public static LwjglxGLPlatform createLwjglxGLPlatform() throws UnsupportedOperationException {
+ public static LwjglxGLPlatform createLwjglxGLPlatform(AppSettings settings) throws UnsupportedOperationException {
+ CHECK_GL_INITAPI.set(true);
switch (Platform.get()) {
case WINDOWS:
return new Win32GLPlatform();
case FREEBSD:
case LINUX:
- return new X11GLPlatform();
+ return JmeSystem.isWaylandSession() && !settings.isX11PlatformPreferred()
+ ? new WaylandGLPlatform()
+ : new X11GLPlatform();
case MACOSX:
return new MacOSXGLPlatform();
default:
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxGLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxGLPlatform.java
index a04ad57923..98f5af81ad 100644
--- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxGLPlatform.java
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxGLPlatform.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2023 jMonkeyEngine
+ * Copyright (c) 2009-2026 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,13 @@
*/
public interface LwjglxGLPlatform extends PlatformGLCanvas {
+ /**
+ * Returns information about the controllers (names) that are being used.
+ *
+ * @return String
+ */
+ String getVideoDriver();
+
/**
* Free the drawing surface.
*/
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/MacOSXGLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/MacOSXGLPlatform.java
index bce9b4c6da..520ecbc164 100644
--- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/MacOSXGLPlatform.java
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/MacOSXGLPlatform.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2023 jMonkeyEngine
+ * Copyright (c) 2009-2026 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,17 @@
*/
final class MacOSXGLPlatform extends PlatformMacOSXGLCanvas implements LwjglxGLPlatform {
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjglx.LwjglxGLPlatform#getVideoDriver()
+ *
+ * @return String
+ */
+ @Override
+ public String getVideoDriver() {
+ return "MacOSX Cocoa NSGL";
+ }
+
/**
* (non-Javadoc)
* @see com.jme3.system.lwjglx.LwjglxGLPlatform#destroy()
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/WaylandGLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/WaylandGLPlatform.java
new file mode 100644
index 0000000000..eaac88d711
--- /dev/null
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/WaylandGLPlatform.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009-2026 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.system.lwjglx;
+
+import org.lwjgl.opengl.awt.PlatformLinuxEGLCanvas;
+import org.lwjgl.system.Platform;
+
+/**
+ * WaylandGLPlatform class that implements the {@link com.jme3.system.lwjglx.LwjglxGLPlatform}
+ * interface for the Linux (Based) platform with Wayland.
+ *
+ * @author wil
+ */
+final class WaylandGLPlatform extends PlatformLinuxEGLCanvas implements LwjglxGLPlatform {
+
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjglx.LwjglxGLPlatform#getVideoDriver()
+ *
+ * @return String
+ */
+ @Override
+ public String getVideoDriver() {
+ Platform platform = Platform.get();
+ return (platform == Platform.FREEBSD
+ ? "FreeBSD" : "Linux")
+ + " EGL XWayland";
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjglx.LwjglxGLPlatform#destroy()
+ */
+ @Override
+ public void destroy() { }
+}
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/Win32GLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/Win32GLPlatform.java
index 9312606979..282e654af8 100644
--- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/Win32GLPlatform.java
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/Win32GLPlatform.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2023 jMonkeyEngine
+ * Copyright (c) 2009-2026 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,17 @@
*/
final class Win32GLPlatform extends PlatformWin32GLCanvas implements LwjglxGLPlatform {
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjglx.LwjglxGLPlatform#getVideoDriver()
+ *
+ * @return String
+ */
+ @Override
+ public String getVideoDriver() {
+ return "Win32 WGL";
+ }
+
/* (non-Javadoc)
* @see com.jme3.system.lwjglx.LwjglxGLPlatform#dispose()
*/
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/X11GLPlatform.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/X11GLPlatform.java
index e5930eb7e3..d290469c21 100644
--- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/X11GLPlatform.java
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/X11GLPlatform.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2023 jMonkeyEngine
+ * Copyright (c) 2009-2026 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
package com.jme3.system.lwjglx;
import org.lwjgl.opengl.awt.*;
+import org.lwjgl.system.Platform;
import static org.lwjgl.opengl.GLX.*;
import static org.lwjgl.system.MemoryUtil.*;
@@ -45,6 +46,20 @@
*/
final class X11GLPlatform extends PlatformLinuxGLCanvas implements LwjglxGLPlatform {
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjglx.LwjglxGLPlatform#getVideoDriver()
+ *
+ * @return String
+ */
+ @Override
+ public String getVideoDriver() {
+ Platform platform = Platform.get();
+ return (platform == Platform.FREEBSD
+ ? "FreeBSD" : "Linux")
+ + " X11 GLX";
+ }
+
/**
* Returns a pointer to the {@code Display*} of the current X11 window using
* AWT.