Skip to content

Commit bcf3349

Browse files
committed
fix: fix the canvas tearing problem with lwjglx.
1 parent 77af9bc commit bcf3349

4 files changed

Lines changed: 116 additions & 36 deletions

File tree

jme3-examples/src/main/java/jme3test/awt/TestCanvas.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ public static void createCanvas(String appClass){
210210
// Note: Only for Linux and Wayland platforms, forces you to
211211
// use XWayland (x11) with awt.
212212
settings.setX11PlatformPreferred(true);
213+
settings.setRenderer(AppSettings.LWJGL_OPENGL32);
213214
settings.setWidth(640);
214215
settings.setHeight(480);
215216

jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglCanvas.java

Lines changed: 85 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777

7878
import static org.lwjgl.system.MemoryUtil.*;
7979
import static com.jme3.system.lwjglx.LwjglxDefaultGLPlatform.*;
80+
import org.lwjgl.system.Platform;
8081

8182
/**
8283
* Class <code>LwjglCanvas</code> that integrates <a href="https://github.com/LWJGLX/lwjgl3-awt">LWJGLX</a>
@@ -116,47 +117,53 @@ public class LwjglCanvas extends LwjglWindow implements JmeCanvasContext, Runnab
116117

117118
/*
118119
Register the different versions.
120+
121+
The 'COMPATIBILITY' profile is used for operational reasons on different
122+
platforms.
123+
124+
see the discussion:
125+
https://github.com/jMonkeyEngine/jmonkeyengine/pull/2153#issuecomment-1860913192
119126
*/
120127
static {
121128
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL32, (data) -> {
122129
data.majorVersion = 3;
123130
data.minorVersion = 2;
124-
data.profile = GLData.Profile.CORE;
131+
data.profile = GLData.Profile.COMPATIBILITY;
125132
});
126133
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL33, (data) -> {
127134
data.majorVersion = 3;
128135
data.minorVersion = 3;
129-
data.profile = GLData.Profile.CORE;
136+
data.profile = GLData.Profile.COMPATIBILITY;
130137
});
131138
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL40, (data) -> {
132139
data.majorVersion = 4;
133140
data.minorVersion = 0;
134-
data.profile = GLData.Profile.CORE;
141+
data.profile = GLData.Profile.COMPATIBILITY;
135142
});
136143
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL41, (data) -> {
137144
data.majorVersion = 4;
138145
data.minorVersion = 1;
139-
data.profile = GLData.Profile.CORE;
146+
data.profile = GLData.Profile.COMPATIBILITY;
140147
});
141148
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL42, (data) -> {
142149
data.majorVersion = 4;
143150
data.minorVersion = 2;
144-
data.profile = GLData.Profile.CORE;
151+
data.profile = GLData.Profile.COMPATIBILITY;
145152
});
146153
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL43, (data) -> {
147154
data.majorVersion = 4;
148155
data.minorVersion = 3;
149-
data.profile = GLData.Profile.CORE;
156+
data.profile = GLData.Profile.COMPATIBILITY;
150157
});
151158
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL44, (data) -> {
152159
data.majorVersion = 4;
153160
data.minorVersion = 4;
154-
data.profile = GLData.Profile.CORE;
161+
data.profile = GLData.Profile.COMPATIBILITY;
155162
});
156163
RENDER_CONFIGS.put(AppSettings.LWJGL_OPENGL45, (data) -> {
157164
data.majorVersion = 4;
158165
data.minorVersion = 5;
159-
data.profile = GLData.Profile.CORE;
166+
data.profile = GLData.Profile.COMPATIBILITY;
160167
});
161168
}
162169

@@ -452,6 +459,47 @@ public void componentResized(ComponentEvent e) {
452459
});
453460
}
454461

462+
/**
463+
* Returns the GL context handler.
464+
*
465+
* @return String
466+
*/
467+
@Override
468+
protected String getCurrentVideoDriver() {
469+
StringBuilder buffer = new StringBuilder();
470+
buffer.append("AWT|Swing (LWJGLX) GLv")
471+
.append(canvas.data.majorVersion)
472+
.append('.')
473+
.append(canvas.data.minorVersion);
474+
475+
String driver = isWayland() ? "(XWayland|X11) GLX" : "X11 GLX";
476+
477+
Platform platform = Platform.get();
478+
if (null == platform) {
479+
buffer.append(" Unknown NULL");
480+
} else {
481+
switch (platform) {
482+
case FREEBSD:
483+
buffer.append(" FreeBSD ")
484+
.append(driver);
485+
break;
486+
case LINUX:
487+
buffer.append(" Linux ")
488+
.append(driver);
489+
break;
490+
case MACOSX:
491+
buffer.append(" MacOSX Cocoa NSGL");
492+
break;
493+
case WINDOWS:
494+
buffer.append(" Win32 WGL");
495+
break;
496+
default:
497+
break;
498+
}
499+
}
500+
return String.valueOf(buffer);
501+
}
502+
455503
/**
456504
* Check if the canvas is displayed, that is, if it has a parent that has set it up.
457505
* <p>
@@ -688,7 +736,7 @@ protected void createContext(AppSettings settings) {
688736
}
689737

690738
glData.alphaSize = settings.getAlphaBits();
691-
glData.sRGB = settings.isGammaCorrection() && !useAuxFramebufferSrgb();
739+
glData.sRGB = settings.isGammaCorrection(); // Not compatible with very old devices
692740

693741
glData.depthSize = settings.getDepthBits();
694742
glData.stencilSize = settings.getStencilBits();
@@ -697,7 +745,11 @@ protected void createContext(AppSettings settings) {
697745

698746
glData.debug = settings.isGraphicsDebug();
699747
glData.api = GLData.API.GL;
700-
glData.forwardCompatible = true;
748+
749+
/* This is done to prevent the context from breaking in Windows,
750+
* since the 'CORE' profile causes rendering failures (black screen).
751+
*/
752+
glData.forwardCompatible = false;
701753

702754
allowSwapBuffers = settings.isSwapBuffers();
703755

@@ -766,7 +818,7 @@ public JoyInput getJoyInput() {
766818
/** (non-Javadoc) */
767819
@Override protected void showWindow() { }
768820
/** (non-Javadoc) */
769-
@Override protected void setWindowIcon(final AppSettings settings) { }
821+
@Override protected void setWindowIcon(final AppSettings settings) { }
770822
/**(non-Javadoc) */
771823
@Override public Vector2f getWindowContentScale(Vector2f store) {
772824
return store == null ? new Vector2f() : store;
@@ -1005,4 +1057,26 @@ public int getPrimaryDisplay() {
10051057
public Canvas getCanvas() {
10061058
return canvas;
10071059
}
1060+
1061+
/**
1062+
* {@inheritDoc}
1063+
* @param settings AppSettings
1064+
*/
1065+
@Override
1066+
public void setSettings(AppSettings settings) {
1067+
if (settings.getRenderer().equals(AppSettings.ANGLE_GLES3)) {
1068+
StringBuilder buffer = new StringBuilder();
1069+
buffer.append("LWJGX is not compatible with ANGLE/SDL or GLES, as it only supports the following:")
1070+
.append('\n').append(" * WGL | Windows")
1071+
.append('\n').append(" * GLX | Linux (X11/XWayland)")
1072+
.append('\n').append(" * CGL | MacOsX")
1073+
.append('\n').append(" * Therefore, version ")
1074+
.append(AppSettings.LWJGL_OPENGL32)
1075+
.append("(3.2) will be used for the GL context.");
1076+
1077+
LOGGER.log(Level.WARNING, String.valueOf(buffer));
1078+
settings.setRenderer(AppSettings.LWJGL_OPENGL32);
1079+
}
1080+
super.setSettings(settings);
1081+
}
10081082
}

jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2023 jMonkeyEngine
2+
* Copyright (c) 2009-2026 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -29,7 +29,6 @@
2929
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3030
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3131
*/
32-
3332
package com.jme3.system.lwjgl;
3433

3534
import com.jme3.input.JoyInput;
@@ -55,28 +54,27 @@
5554
import com.jme3.util.LWJGLBufferAllocator.ConcurrentLWJGLBufferAllocator;
5655
import com.jme3.util.LWJGLSaferAllocMemoryAllocator;
5756

58-
import static com.jme3.util.LWJGLBufferAllocator.PROPERTY_CONCURRENT_BUFFER_ALLOCATOR;
5957
import java.nio.IntBuffer;
6058
import java.util.*;
6159
import java.util.concurrent.atomic.AtomicBoolean;
6260
import java.util.logging.Level;
6361
import java.util.logging.Logger;
62+
6463
import org.lwjgl.Version;
6564
import org.lwjgl.opengl.ARBDebugOutput;
6665
import org.lwjgl.opengl.ARBFramebufferObject;
6766
import org.lwjgl.opengl.EXTFramebufferMultisample;
6867
import org.lwjgl.opengl.GL11;
6968
import org.lwjgl.opengl.GL30;
70-
71-
import static org.lwjgl.opengl.GL.createCapabilities;
72-
import static org.lwjgl.opengl.GL11.glGetInteger;
7369
import org.lwjgl.opengl.GLCapabilities;
7470
import org.lwjgl.opengles.GLES;
7571
import org.lwjgl.opengles.GLES30;
7672
import org.lwjgl.opengles.GLESCapabilities;
77-
import static org.lwjgl.sdl.SDLVideo.*;
7873
import org.lwjgl.system.Configuration;
79-
import org.lwjgl.system.MemoryStack;
74+
75+
import static org.lwjgl.opengl.GL.createCapabilities;
76+
import static org.lwjgl.opengl.GL11.glGetInteger;
77+
import static com.jme3.util.LWJGLBufferAllocator.PROPERTY_CONCURRENT_BUFFER_ALLOCATOR;
8078

8179
/**
8280
* A LWJGL implementation of a graphics context.
@@ -149,11 +147,13 @@ public void setSystemListener(final SystemListener listener) {
149147

150148
protected void printContextInitInfo() {
151149
if (logger.isLoggable(Level.INFO)) {
152-
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n * Video backend: SDL {2}",
153-
APIUtil.toArray(Version.getVersion(), Thread.currentThread().getName(), SDL_GetCurrentVideoDriver()));
150+
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n * Video backend: {2}",
151+
APIUtil.toArray(Version.getVersion(), Thread.currentThread().getName(), getCurrentVideoDriver()));
154152
}
155153
}
156154

155+
protected abstract String getCurrentVideoDriver();
156+
157157
protected int determineMaxSamples() {
158158
final GLCapabilities capabilities = org.lwjgl.opengl.GL.getCapabilities();
159159
if (capabilities.GL_ARB_framebuffer_object) {

jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,6 @@
3131
*/
3232
package com.jme3.system.lwjgl;
3333

34-
import static org.lwjgl.egl.EXTPlatformWayland.EGL_PLATFORM_WAYLAND_EXT;
35-
import static org.lwjgl.egl.EXTPlatformX11.EGL_PLATFORM_X11_EXT;
36-
import static org.lwjgl.sdl.SDLError.*;
37-
import static org.lwjgl.sdl.SDLEvents.*;
38-
import static org.lwjgl.sdl.SDLHints.*;
39-
import static org.lwjgl.sdl.SDLInit.*;
40-
import static org.lwjgl.sdl.SDLKeyboard.*;
41-
import static org.lwjgl.sdl.SDLMouse.*;
42-
import static org.lwjgl.sdl.SDLPixels.*;
43-
import static org.lwjgl.sdl.SDLSurface.*;
44-
import static org.lwjgl.sdl.SDLStdinc.SDL_setenv_unsafe;
45-
import static org.lwjgl.sdl.SDLVideo.*;
46-
import static org.lwjgl.system.MemoryUtil.NULL;
47-
4834
import com.jme3.app.Application;
4935
import com.jme3.asset.AssetManager;
5036
import com.jme3.input.JoyInput;
@@ -75,6 +61,8 @@
7561
import com.jme3.ui.Picture;
7662
import com.jme3.util.BufferUtils;
7763
import com.jme3.util.SafeArrayList;
64+
import com.jme3.renderer.opengl.GLRenderer;
65+
7866
import java.awt.Graphics2D;
7967
import java.awt.image.BufferedImage;
8068
import java.nio.ByteBuffer;
@@ -85,14 +73,26 @@
8573
import java.util.concurrent.atomic.AtomicBoolean;
8674
import java.util.logging.Level;
8775
import java.util.logging.Logger;
76+
8877
import org.lwjgl.Version;
8978
import org.lwjgl.sdl.SDL_DisplayMode;
9079
import org.lwjgl.sdl.SDL_Event;
9180
import org.lwjgl.sdl.SDL_Surface;
9281
import org.lwjgl.sdl.SDLStdinc;
9382
import org.lwjgl.system.Configuration;
9483
import org.lwjgl.system.MemoryStack;
95-
import com.jme3.renderer.opengl.GLRenderer;
84+
85+
import static org.lwjgl.egl.EXTPlatformWayland.EGL_PLATFORM_WAYLAND_EXT;
86+
import static org.lwjgl.egl.EXTPlatformX11.EGL_PLATFORM_X11_EXT;
87+
import static org.lwjgl.sdl.SDLError.*;
88+
import static org.lwjgl.sdl.SDLEvents.*;
89+
import static org.lwjgl.sdl.SDLHints.*;
90+
import static org.lwjgl.sdl.SDLInit.*;
91+
import static org.lwjgl.sdl.SDLPixels.*;
92+
import static org.lwjgl.sdl.SDLSurface.*;
93+
import static org.lwjgl.sdl.SDLStdinc.SDL_setenv_unsafe;
94+
import static org.lwjgl.sdl.SDLVideo.*;
95+
import static org.lwjgl.system.MemoryUtil.NULL;
9696

9797
/**
9898
* SDL3-backed window/context implementation for LWJGL 3.4+.
@@ -243,6 +243,11 @@ private static void disableNvidiaThreadedOptimizations() {
243243
}
244244
}
245245

246+
@Override
247+
protected String getCurrentVideoDriver() {
248+
return "SDL " + SDL_GetCurrentVideoDriver();
249+
}
250+
246251
@Override
247252
public JmeContext.Type getType() {
248253
return type;

0 commit comments

Comments
 (0)