diff --git a/jme3-examples/build.gradle b/jme3-examples/build.gradle
index b5979feceb..7fd7034dae 100644
--- a/jme3-examples/build.gradle
+++ b/jme3-examples/build.gradle
@@ -19,8 +19,8 @@ dependencies {
implementation project(':jme3-effects')
implementation project(':jme3-jbullet')
implementation project(':jme3-jogg')
- implementation project(':jme3-lwjgl')
-// implementation project(':jme3-lwjgl3')
+// implementation project(':jme3-lwjgl')
+ implementation project(':jme3-lwjgl3')
implementation project(':jme3-networking')
implementation project(':jme3-niftygui')
implementation project(':jme3-plugins')
diff --git a/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java b/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java
index bb4b39ac95..5f97ba8c27 100644
--- a/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java
+++ b/jme3-examples/src/main/java/jme3test/awt/TestCanvas.java
@@ -29,7 +29,6 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
package jme3test.awt;
import com.jme3.app.LegacyApplication;
@@ -171,7 +170,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();
diff --git a/jme3-lwjgl3/build.gradle b/jme3-lwjgl3/build.gradle
index f035ac7229..e20ce923b9 100644
--- a/jme3-lwjgl3/build.gradle
+++ b/jme3-lwjgl3/build.gradle
@@ -1,9 +1,12 @@
dependencies {
api project(':jme3-core')
api project(':jme3-desktop')
+
+ api "org.lwjglx:lwjgl3-awt:0.1.8"
api "org.lwjgl:lwjgl:${lwjgl3Version}"
api "org.lwjgl:lwjgl-glfw:${lwjgl3Version}"
+ api "org.lwjgl:lwjgl-jawt:${lwjgl3Version}"
api "org.lwjgl:lwjgl-jemalloc:${lwjgl3Version}"
api "org.lwjgl:lwjgl-openal:${lwjgl3Version}"
api "org.lwjgl:lwjgl-opencl:${lwjgl3Version}"
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 0614cba16c..e5e13117e2 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
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2022 jMonkeyEngine
+ * Copyright (c) 2009-2024 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,151 +37,538 @@
import com.jme3.input.awt.AwtMouseInput;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
-import com.jme3.system.JmeContext.Type;
-import com.jme3.texture.FrameBuffer;
-import com.jme3.texture.FrameBuffer.FrameBufferTarget;
-import com.jme3.texture.Image;
-import com.jme3.util.BufferUtils;
-import com.jme3.util.Screenshots;
+import com.jme3.system.lwjglx.LwjglxGLPlatform;
+
import java.awt.AWTException;
-import java.awt.BufferCapabilities;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
-import java.awt.ImageCapabilities;
-import java.awt.RenderingHints;
+import java.awt.GraphicsConfiguration;
+import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
import java.awt.geom.AffineTransform;
-import java.awt.image.AffineTransformOp;
-import java.awt.image.BufferStrategy;
-import java.awt.image.BufferedImage;
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.lwjgl.awthacks.NonClearGraphics;
+import org.lwjgl.awthacks.NonClearGraphics2D;
+import org.lwjgl.opengl.awt.GLData;
+import org.lwjgl.system.Platform;
+
+import static org.lwjgl.system.MemoryUtil.*;
+import static com.jme3.system.lwjglx.LwjglxDefaultGLPlatform.*;
+
+/**
+ * Class LwjglCanvas
that integrates LWJGLX
+ * which allows using AWT-Swing components.
+ *
+ *
+ * If LwjglCanvas throws an exception due to configuration problems, we can debug as follows:
+ *
+ * - In AppSettings
, set this property to enable a debug that displays
+ * the effective data for the context.
+ *
+ * ....
+ * AppSettings settings = new AppSettings(true);
+ * settings.putBoolean("GLDataEffectiveDebug", true);
+ * ...
+ *
+ *
+ *
+ * NOTE: If running LwjglCanvas
on older machines, the SRGB | Gamma Correction
option
+ * will raise an exception, so it should be disabled.
+ *
+ * ....
+ * AppSettings settings = new AppSettings(true);
+ * settings.setGammaCorrection(false);
+ * ...
+ *
+ *
+ * @author wil
+ */
public class LwjglCanvas extends LwjglWindow implements JmeCanvasContext, Runnable {
- private static final Logger logger = Logger.getLogger(LwjglCanvas.class.getName());
-
- private final Canvas canvas;
-
- private BufferedImage img;
- private FrameBuffer fb;
-
- private ByteBuffer byteBuf;
- private IntBuffer intBuf;
-
- private BufferStrategy strategy;
- private AffineTransformOp transformOp;
+ /** Logger class. */
+ private static final Logger LOGGER = Logger.getLogger(LwjglCanvas.class.getName());
+
+ /** GL versions map. */
+ private static final Mapjava.awt.Canvas
that supports to be drawn on using OpenGL.
+ */
+ private class LwjglAWTGLCanvas extends Canvas {
+
+ /**
+ * A {@link com.jme3.system.lwjglx.LwjglxGLPlatform} object.
+ * @see org.lwjgl.opengl.awt.PlatformGLCanvas
+ */
+ private LwjglxGLPlatform platformCanvas;
+
+ /** The OpenGL context (LWJGL3-AWT). */
+ private long context;
+
+ /**
+ * Information object used to create the OpenGL context.
+ */
+ private GLData data;
+
+ /** Effective data to initialize the context. */
+ private GLData effective;
+
+ /**
+ * Constructor of the LwjglAWTGLCanva
class where objects are
+ * initialized for OpenGL-AWT rendering
+ *
+ * @param data A {@link org.lwjgl.opengl.awt.GLData} object
+ */
+ public LwjglAWTGLCanvas(GLData data) {
+ this.effective = new GLData();
+ this.context = NULL;
+ this.data = data;
+
+ try {
+ platformCanvas = createLwjglxGLPlatform();
+ } catch (UnsupportedOperationException e) {
+ listener.handleError(e.getLocalizedMessage(), e);
+ }
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see java.awt.Component#addComponentListener(java.awt.event.ComponentListener)
+ * @param l object-listener
+ */
+ @Override
+ public synchronized void addComponentListener(ComponentListener l) {
+ super.addComponentListener(l);
+ }
+
+ /**
+ * Returns the effective data (recommended or ideal) to initialize the
+ * LWJGL3-AWT context.
+ *
+ * @return A {@link org.lwjgl.opengl.awt.GLData} object
+ */
+ public GLData getGLDataEffective() {
+ return effective;
+ }
+
+ /**
+ * Called after beforeRender()
to release the threads (unlock);
+ * so that AWT can update its threads normally.
+ *
+ * NOTE: It is very important to call this method and not leave AWT
+ * hanging (breaking it) regardless of whether an error occurs during OpenGL
+ * rendering.
+ */
+ public void afterRender() {
+ // release the rendering context
+ platformCanvas.makeCurrent(NULL);
+ try {
+ platformCanvas.unlock(); // <- MUST unlock on Linux
+ } catch (AWTException e) {
+ listener.handleError("Failed to unlock Canvas", e);
+ }
+ }
+
+ /**
+ * Called before afterRender()
to prepare the AWT drawing surface.
+ */
+ public void beforeRender() {
+ // this is where the OpenGL rendering context is generated.
+ if (context == NULL) {
+ try {
+ context = platformCanvas.create(this, data, effective);
+ } catch (AWTException e) {
+ listener.handleError("Exception while creating the OpenGL context", e);
+ return;
+ }
+ }
+
+ /*
+ * To start drawing on the AWT surface, the AWT threads must be locked to
+ * avoid conflicts when drawing on the canvas.
+ */
+ try {
+ platformCanvas.lock(); // <- MUST lock on Linux
+ } catch (AWTException e) {
+ listener.handleError("Failed to lock Canvas", e);
+ }
+
+ /*
+ * The 'makeCurrent(long)' method converts the specified OpenGL rendering
+ * context to the current rendering context.
+ */
+ platformCanvas.makeCurrent(context);
+ }
+
+ /**
+ * Frees up the drawing surface (only on Windows and MacOSX).
+ */
+ public void doDisposeCanvas() {
+ if (OS != Platform.LINUX) {
+ platformCanvas.dispose();
+ }
+ }
+
+ /**
+ * This is where you actually draw on the canvas (framebuffer).
+ */
+ public void swapBuffers() {
+ platformCanvas.swapBuffers();
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see java.awt.Component#addNotify()
+ */
+ @Override
+ public void addNotify() {
+ super.addNotify();
+ /* you have to notify if the canvas is visible to draw on it. */
+ synchronized (lock) {
+ hasNativePeer.set(true);
+ }
+ requestFocusInWindow();
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see java.awt.Component#removeNotify()
+ */
+ @Override
+ public void removeNotify() {
+ synchronized (lock) {
+ // prepare for a possible re-adding
+ if ((OS != Platform.LINUX) && (context != NULL)) {
+ platformCanvas.deleteContext(context);
+ context = NULL;
+ }
+ hasNativePeer.set(false);
+ }
+ super.removeNotify();
+ if (OS == Platform.WINDOWS) {
+ LOGGER.log(Level.WARNING, "Windows does not support this functionality: remove(__canvas__)");
+ }
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjglx.LwjglxGLPlatform#destroy()
+ */
+ public void destroy() {
+ platformCanvas.destroy();
+ }
+
+ /**
+ * Returns Graphics object that ignores {@link java.awt.Graphics#clearRect(int, int, int, int)}
+ * calls.
+ *
+ * This is done so that the frame buffer will not be cleared by AWT/Swing internals.
+ *
+ * @see org.lwjgl.awthacks.NonClearGraphics2D
+ * @see org.lwjgl.awthacks.NonClearGraphics
+ * @return Graphics
+ */
+ @Override
+ public Graphics getGraphics() {
+ Graphics graphics = super.getGraphics();
+ if (graphics instanceof Graphics2D) {
+ return new NonClearGraphics2D((Graphics2D) graphics);
+ }
+ return new NonClearGraphics(graphics);
+ }
+ }
+
+ /** Canvas-AWT. */
+ private final LwjglAWTGLCanvas canvas;
+
+ /**
+ * Configuration data to start the AWT context, this is used by the
+ * {@code lwjgl-awt} library.
+ */
+ private GLData glData;
+
+ /** Used to display the effective data for the {@code AWT-Swing} drawing surface per console. */
+ private final AtomicBoolean showGLDataEffective = new AtomicBoolean(false);
+
+ /** Used to notify the canvas status ({@code remove()/add()}). */
private final AtomicBoolean hasNativePeer = new AtomicBoolean(false);
+
+ /** Notify if the canvas is visible and has a parent.*/
private final AtomicBoolean showing = new AtomicBoolean(false);
-
- private int width = 1;
- private int height = 1;
+
+ /** Notify if there is a change in canvas dimensions. */
private AtomicBoolean needResize = new AtomicBoolean(false);
- private final Object lock = new Object();
+
+ /**
+ * Flag that uses the context to check if it is initialized or not, this prevents
+ * it from being initialized multiple times and potentially breaking the JVM.
+ */
+ private AtomicBoolean contextFlag = new AtomicBoolean(false);
+
+ /** Semaphort used to check the "terminate" signal. */
+ private final Semaphore signalTerminate = new Semaphore(0);
+ /** lock-object. */
+ private final Object lock = new Object();
+
+ /** Framebuffer width. */
+ private int framebufferWidth = 1;
+
+ /** Framebuffer height. */
+ private int framebufferHeight = 1;
+
+ /** AWT keyboard input manager. */
private AwtKeyInput keyInput;
+
+ /** AWT mouse input manager. */
private AwtMouseInput mouseInput;
-
+
+ /**
+ * Generate a new OpenGL context (LwjglCanvas
) to integrate
+ * AWT/Swing with JME3 in your desktop applications.
+ */
public LwjglCanvas() {
super(Type.Canvas);
-
- canvas = new Canvas() {
- @Override
- public void paint(Graphics g) {
- Graphics2D g2d = (Graphics2D) g;
- synchronized (lock) {
- g2d.drawImage(img, transformOp, 0, 0);
- }
- }
-
- @Override
- public void addNotify() {
- super.addNotify();
-
- synchronized (lock) {
- hasNativePeer.set(true);
- }
-
- requestFocusInWindow();
- }
-
+ glData = new GLData();
+ canvas = new LwjglAWTGLCanvas(glData);
+ canvas.setIgnoreRepaint(true);
+
+ // To determine the size of the framebuffer every time the user resizes
+ // the canvas (this works if the component has a parent)
+ canvas.addComponentListener(new ComponentAdapter() {
@Override
- public void removeNotify() {
+ public void componentResized(ComponentEvent e) {
synchronized (lock) {
- hasNativePeer.set(false);
- }
+ GraphicsConfiguration gc = canvas.getGraphicsConfiguration();
+ if (gc == null) {
+ return;
+ }
+
+ AffineTransform at = gc.getDefaultTransform();
+ float sx = (float) at.getScaleX(),
+ sy = (float) at.getScaleY();
- super.removeNotify();
- }
- };
- canvas.addComponentListener(new ComponentAdapter() {
+ int fw = (int) (canvas.getWidth() * sx);
+ int fh = (int) (canvas.getHeight() * sy);
- @Override
- public void componentResized(ComponentEvent e) {
- synchronized (lock) {
- int newWidth = Math.max(canvas.getWidth(), 1);
- int newHeight = Math.max(canvas.getHeight(), 1);
- if (width != newWidth || height != newHeight) {
- width = newWidth;
- height = newHeight;
+ if (fw != framebufferWidth || fh != framebufferHeight) {
+ framebufferWidth = Math.max(fw, 1);
+ framebufferHeight = Math.max(fh, 1);
needResize.set(true);
}
}
- }
+ }
});
- canvas.setFocusable(true);
- canvas.setIgnoreRepaint(true);
}
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.JmeContext#destroy(boolean)
+ * @param waitFor boolean
+ */
@Override
- public Canvas getCanvas() {
- return canvas;
+ public void destroy(boolean waitFor) {
+ super.destroy(waitFor);
+ this.contextFlag.set(false);
}
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.JmeContext#create(boolean)
+ * @param waitFor boolean
+ */
@Override
- protected void showWindow() {
+ public void create(boolean waitFor) {
+ if (this.contextFlag.get()) {
+ return;
+ }
+ // create context
+ super.create(waitFor);
+ this.contextFlag.set(true);
}
-
+
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjgl.LwjglWindow#createContext(com.jme3.system.AppSettings)
+ * @param settings A {@link com.jme3.system.AppSettings} object
+ */
@Override
- protected void setWindowIcon(final AppSettings settings) {
+ protected void createContext(AppSettings settings) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ex) {
+ LOGGER.log(Level.SEVERE, "LWJGL3-AWT: Interrupted!", ex);
+ }
+
+ super.createContext(settings);
+ RENDER_CONFIGS.computeIfAbsent(settings.getRenderer(), (t) -> {
+ return (data) -> {
+ data.majorVersion = 2;
+ data.minorVersion = 0;
+ };
+ }).accept(glData);
+
+ if (settings.getBitsPerPixel() == 24) {
+ glData.redSize = 8;
+ glData.greenSize = 8;
+ glData.blueSize = 8;
+ } else if (settings.getBitsPerPixel() == 16) {
+ glData.redSize = 5;
+ glData.greenSize = 6;
+ glData.blueSize = 5;
+ }
+
+ // Enable vsync for LWJGL3-AWT
+ if (settings.isVSync()) {
+ glData.swapInterval = 1;
+ } else {
+ glData.swapInterval = 0;
+ }
+
+ // This will activate the "effective data" scrubber.
+ showGLDataEffective.set(settings.getBoolean("GLDataEffectiveDebug"));
+
+ glData.depthSize = settings.getBitsPerPixel();
+ glData.alphaSize = settings.getAlphaBits();
+ glData.sRGB = settings.isGammaCorrection(); // Not compatible with very old devices
+
+ glData.depthSize = settings.getDepthBits();
+ glData.stencilSize = settings.getStencilBits();
+ glData.samples = settings.getSamples();
+ glData.stereo = settings.useStereo3D();
+
+ glData.debug = settings.isGraphicsDebug();
+ glData.api = GLData.API.GL;
}
-
+
+ /**
+ * Returns the AWT component where it is drawn (canvas).
+ * @return Canvas
+ */
@Override
- public void setTitle(String title) {
+ public Canvas getCanvas() {
+ return canvas;
}
+ /** (non-Javadoc) */
+ @Override
+ protected void showWindow() { }
+ /** (non-Javadoc) */
+ @Override
+ protected void setWindowIcon(final AppSettings settings) { }
+ /** (non-Javadoc) */
+ @Override
+ public void setTitle(String title) { }
+
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjgl.LwjglWindow#getKeyInput()
+ * @return returns a {@link com.jme3.input.awt.AwtKeyInput} object
+ */
@Override
public KeyInput getKeyInput() {
if (keyInput == null) {
keyInput = new AwtKeyInput();
keyInput.setInputSource(canvas);
}
-
return keyInput;
}
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjgl.LwjglWindow#getMouseInput()
+ * @return returns a {@link com.jme3.input.awt.AwtMouseInput} object
+ */
@Override
public MouseInput getMouseInput() {
if (mouseInput == null) {
mouseInput = new AwtMouseInput();
mouseInput.setInputSource(canvas);
}
-
return mouseInput;
}
+ /**
+ * Check if the canvas is displayed, that is, if it has a parent that has set it up.
+ *
+ * It is very important that this verification be done so that LWJGL3-AWT works correctly.
+ *
+ * @return returns true
if the canvas is ready to draw; otherwise
+ * returns false
+ */
public boolean checkVisibilityState() {
if (!hasNativePeer.get()) {
synchronized (lock) {
- if (strategy != null) {
- strategy.dispose();
- strategy = null;
- }
+ canvas.doDisposeCanvas();
}
return false;
}
@@ -191,111 +578,179 @@ public boolean checkVisibilityState() {
return currentShowing;
}
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjgl.LwjglWindow#destroyContext()
+ */
@Override
protected void destroyContext() {
synchronized (lock) {
- destroyFrameBuffer();
- img = null;
- byteBuf = null;
- intBuf = null;
+ canvas.destroy();
}
+ // request the cleanup
+ signalTerminate.release();
super.destroyContext();
}
- @Override
- protected void createContext(AppSettings settings) {
- super.createContext(settings);
-
- if (renderer != null) {
- createFrameBuffer(width, height);
- }
- }
-
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjgl.LwjglWindow#runLoop()
+ */
@Override
protected void runLoop() {
if (needResize.get()) {
needResize.set(false);
- listener.reshape(width, height);
- createFrameBuffer(width, height);
+ settings.setResolution(framebufferWidth, framebufferHeight);
+ listener.reshape(framebufferWidth, framebufferHeight);
}
-
+
+ // check component status
if (!checkVisibilityState()) {
return;
}
- super.runLoop();
-
- drawFrameInThread();
- }
-
- public void drawFrameInThread() {
-
- // Convert screenshot
- byteBuf.clear();
- renderer.readFrameBuffer(fb, byteBuf);
- Screenshots.convertScreenShot2(intBuf, img);
-
- synchronized (lock) {
- // All operations on strategy should be synchronized (?)
- if (strategy == null) {
- try {
- canvas.createBufferStrategy(1,
- new BufferCapabilities(
- new ImageCapabilities(true),
- new ImageCapabilities(true),
- BufferCapabilities.FlipContents.UNDEFINED)
- );
- } catch (AWTException ex) {
- logger.log(Level.SEVERE, "Failed to create buffer strategy!", ex);
- }
- strategy = canvas.getBufferStrategy();
+ //----------------------------------------------------------------------
+ // AWT - RENDERER
+ //----------------------------------------------------------------------
+ /*
+ * The same logic as AWTGLCanvas is used to draw on the awt drawing surface:
+ *
+ * 1. Lock any thread to avoid any conflict.
+ * 2. Buffer swap (this is where the framebuffer is actually drawn): swapBuffers()
+ * 3. Unlock so that the AWT thread can work normally. IF NOT DONE, IT WILL
+ * BE WAITING AND BREAK ANY AWT/Swing APP.
+ */
+ canvas.beforeRender();
+ try {
+ super.runLoop();
+ if (allowSwapBuffers && autoFlush) {
+ canvas.swapBuffers();
}
-
- // Draw screenshot
- do {
- do {
- Graphics2D g2d = (Graphics2D) strategy.getDrawGraphics();
- if (g2d == null) {
- logger.log(Level.WARNING, "OGL: DrawGraphics was null.");
- return;
- }
-
- g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
- RenderingHints.VALUE_RENDER_QUALITY);
-
- g2d.drawImage(img, transformOp, 0, 0);
- g2d.dispose();
- strategy.show();
- } while (strategy.contentsRestored());
- } while (strategy.contentsLost());
+ } finally {
+ canvas.afterRender();
+ }
+
+ // Sync the display on some systems.
+ Toolkit.getDefaultToolkit().sync();
+
+ //----------------------------------------------------------------------
+ /*
+ * Whether it is necessary to know the effective attributes to
+ * initialize the LWJGL3-AWT context
+ */
+ //----------------------------------------------------------------------
+ if (showGLDataEffective.get()) {
+ showGLDataEffective.set(false);
+ System.out.println(MessageFormat.format("[ DEBUGGER ] :Effective data to initialize the LWJGL3-AWT context\n{0}",
+ getPrintContextInitInfo(canvas.getGLDataEffective())));
}
- }
-
- private void createFrameBuffer(int width, int height) {
- byteBuf = BufferUtils.ensureLargeEnough(byteBuf, width * height * 4);
- intBuf = byteBuf.asIntBuffer();
-
- destroyFrameBuffer();
-
- fb = new FrameBuffer(width, height, settings.getSamples());
- fb.setDepthTarget(FrameBufferTarget.newTarget(Image.Format.Depth));
- fb.addColorTarget(FrameBufferTarget.newTarget(Image.Format.RGB8));
- fb.setSrgb(settings.isGammaCorrection());
-
- renderer.setMainFrameBufferOverride(fb);
-
- img = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
- AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
- tx.translate(0, -img.getHeight());
- transformOp = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+ try {
+ if (signalTerminate.tryAcquire(10, TimeUnit.MILLISECONDS)) {
+ canvas.doDisposeCanvas();
+ }
+ } catch (InterruptedException ignored) { }
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjgl.LwjglContext#printContextInitInfo()
+ */
+ @Override
+ protected void printContextInitInfo() {
+ super.printContextInitInfo();
+ LOGGER.log(Level.INFO, "Initializing LWJGL3-AWT with jMonkeyEngine\n{0}", getPrintContextInitInfo(glData));
+ }
+
+ /**
+ * Returns a string with the information obtained from GLData
+ * so that it can be displayed.
+ *
+ * @param glData context information
+ * @return String
+ */
+ protected String getPrintContextInitInfo(GLData glData) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(" * Double Buffer: ").append(glData.doubleBuffer);
+ sb.append('\n')
+ .append(" * Stereo: ").append(glData.stereo);
+ sb.append('\n')
+ .append(" * Red Size: ").append(glData.redSize);
+ sb.append('\n')
+ .append(" * Rreen Size: ").append(glData.greenSize);
+ sb.append('\n')
+ .append(" * Blue Size: ").append(glData.blueSize);
+ sb.append('\n')
+ .append(" * Alpha Size: ").append(glData.alphaSize);
+ sb.append('\n')
+ .append(" * Depth Size: ").append(glData.depthSize);
+ sb.append('\n')
+ .append(" * Stencil Size: ").append(glData.stencilSize);
+ sb.append('\n')
+ .append(" * Accum Red Size: ").append(glData.accumRedSize);
+ sb.append('\n')
+ .append(" * Accum Green Size: ").append(glData.accumGreenSize);
+ sb.append('\n')
+ .append(" * Accum Blue Size: ").append(glData.accumBlueSize);
+ sb.append('\n')
+ .append(" * Accum Alpha Size: ").append(glData.accumAlphaSize);
+ sb.append('\n')
+ .append(" * Sample Buffers: ").append(glData.sampleBuffers);
+ sb.append('\n')
+ .append(" * Share Context: ").append(glData.shareContext);
+ sb.append('\n')
+ .append(" * Major Version: ").append(glData.majorVersion);
+ sb.append('\n')
+ .append(" * Minor Version: ").append(glData.minorVersion);
+ sb.append('\n')
+ .append(" * Forward Compatible: ").append(glData.forwardCompatible);
+ sb.append('\n')
+ .append(" * Profile: ").append(glData.profile);
+ sb.append('\n')
+ .append(" * API: ").append(glData.api);
+ sb.append('\n')
+ .append(" * Debug: ").append(glData.debug);
+ sb.append('\n')
+ .append(" * Swap Interval: ").append(glData.swapInterval);
+ sb.append('\n')
+ .append(" * SRGB (Gamma Correction): ").append(glData.sRGB);
+ sb.append('\n')
+ .append(" * Pixel Format Float: ").append(glData.pixelFormatFloat);
+ sb.append('\n')
+ .append(" * Context Release Behavior: ").append(glData.contextReleaseBehavior);
+ sb.append('\n')
+ .append(" * Color Samples NV: ").append(glData.colorSamplesNV);
+ sb.append('\n')
+ .append(" * Swap Group NV: ").append(glData.swapGroupNV);
+ sb.append('\n')
+ .append(" * Swap Barrier NV: ").append(glData.swapBarrierNV);
+ sb.append('\n')
+ .append(" * Robustness: ").append(glData.robustness);
+ sb.append('\n')
+ .append(" * Lose Context On Reset: ").append(glData.loseContextOnReset);
+ sb.append('\n')
+ .append(" * Context Reset Isolation: ").append(glData.contextResetIsolation);
+ return String.valueOf(sb);
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjgl.LwjglWindow#getFramebufferHeight()
+ * @return int
+ */
+ @Override
+ public int getFramebufferHeight() {
+ return this.framebufferHeight;
}
- public void destroyFrameBuffer() {
- if (fb != null) {
- fb.dispose();
- fb = null;
- }
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjgl.LwjglWindow#getFramebufferWidth()
+ * @return int
+ */
+ @Override
+ public int getFramebufferWidth() {
+ return this.framebufferWidth;
}
}
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java
index 155693c8b9..4d92383b50 100644
--- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java
@@ -46,6 +46,16 @@
import com.jme3.system.NanoTimer;
import com.jme3.util.BufferUtils;
import com.jme3.util.SafeArrayList;
+
+import org.lwjgl.Version;
+import org.lwjgl.glfw.GLFWErrorCallback;
+import org.lwjgl.glfw.GLFWFramebufferSizeCallback;
+import org.lwjgl.glfw.GLFWImage;
+import org.lwjgl.glfw.GLFWVidMode;
+import org.lwjgl.glfw.GLFWWindowFocusCallback;
+import org.lwjgl.glfw.GLFWWindowSizeCallback;
+import org.lwjgl.system.Platform;
+
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
@@ -55,17 +65,10 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.lwjgl.Version;
+
import static org.lwjgl.glfw.GLFW.*;
-import org.lwjgl.glfw.GLFWErrorCallback;
-import org.lwjgl.glfw.GLFWFramebufferSizeCallback;
-import org.lwjgl.glfw.GLFWImage;
-import org.lwjgl.glfw.GLFWVidMode;
-import org.lwjgl.glfw.GLFWWindowFocusCallback;
-import org.lwjgl.glfw.GLFWWindowSizeCallback;
import static org.lwjgl.opengl.GL11.GL_FALSE;
import static org.lwjgl.system.MemoryUtil.NULL;
-import org.lwjgl.system.Platform;
/**
* A wrapper class over the GLFW framework in LWJGL 3.
@@ -631,9 +634,10 @@ protected void runLoop() {
// If the canvas is not active, there's no need to waste time
// doing that.
if (renderable.get()) {
- // calls swap buffers, etc.
try {
- if (allowSwapBuffers && autoFlush) {
+ // If type is 'Canvas'; lwjgl-awt takes care of swap buffers.
+ if ((type != Type.Canvas) && allowSwapBuffers && autoFlush) {
+ // calls swap buffers, etc.
glfwSwapBuffers(window);
}
} catch (Throwable ex) {
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/Sync.java b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/Sync.java
index db9beef520..3161f00a9b 100644
--- a/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/Sync.java
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/Sync.java
@@ -31,7 +31,6 @@
*/
package com.jme3.system.lwjgl;
-
/**
* A highly accurate sync method that continually adapts to the system
* it runs on to provide reliable results.
@@ -41,8 +40,6 @@
*/
class Sync {
-
-
/** number of nanoseconds in a second */
private static final long NANOS_IN_SECOND = 1000L * 1000L * 1000L;
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
new file mode 100644
index 0000000000..3f7be3bcf3
--- /dev/null
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxDefaultGLPlatform.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009-2023 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.system.Platform;
+import static org.lwjgl.system.Platform.*;
+
+/**
+ * Class wjglxDefaultGLPlatform
used to create a drawing platform.
+ * @author wil
+ */
+public final class LwjglxDefaultGLPlatform {
+
+ /**
+ * Returns a drawing platform based on the platform it is running on.
+ * @return LwjglxGLPlatform
+ * @throws UnsupportedOperationException throws exception if platform is not supported
+ */
+ public static LwjglxGLPlatform createLwjglxGLPlatform() throws UnsupportedOperationException {
+ switch (Platform.get()) {
+ case WINDOWS:
+ return new Win32GLPlatform();
+ //case FREEBSD: -> In future versions of lwjgl3 (possibly)
+ case LINUX:
+ return new X11GLPlatform();
+ case MACOSX:
+ return new MacOSXGLPlatform();
+ default:
+ throw new UnsupportedOperationException("Platform " + Platform.get() + " not yet supported");
+ }
+ }
+
+ /**
+ * private constructor.
+ */
+ private LwjglxDefaultGLPlatform() {}
+}
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
new file mode 100644
index 0000000000..a04ad57923
--- /dev/null
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/LwjglxGLPlatform.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2009-2023 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.PlatformGLCanvas;
+
+/**
+ * Interface LwjglxGLPlatform
; It is used to implement and manage
+ * the context of a specific platform.
+ *
+ * @author wil
+ */
+public interface LwjglxGLPlatform extends PlatformGLCanvas {
+
+ /**
+ * Free the drawing surface.
+ */
+ public void destroy();
+}
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
new file mode 100644
index 0000000000..bce9b4c6da
--- /dev/null
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/MacOSXGLPlatform.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009-2023 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.PlatformMacOSXGLCanvas;
+import static org.lwjgl.system.jawt.JAWTFunctions.*;
+
+/**
+ * MacOSXGLPlatform
class that implements the {@link com.jme3.system.lwjglx.LwjglxGLPlatform}
+ * interface for the MacOS platform.
+ *
+ * @author wil
+ */
+final class MacOSXGLPlatform extends PlatformMacOSXGLCanvas implements LwjglxGLPlatform {
+
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjglx.LwjglxGLPlatform#destroy()
+ */
+ @Override
+ public void destroy() {
+ if (ds != null) {
+ JAWT_FreeDrawingSurface(ds, awt.FreeDrawingSurface());
+ awt.free();
+ }
+ }
+ }
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
new file mode 100644
index 0000000000..794498a52c
--- /dev/null
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/Win32GLPlatform.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009-2023 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 static org.lwjgl.system.jawt.JAWTFunctions.*;
+import org.lwjgl.opengl.awt.PlatformWin32GLCanvas;
+
+/**
+ * Win32GLPlatform
class that implements the {@link com.jme3.system.lwjglx.LwjglxGLPlatform}
+ * interface for the Windows (Win32) platform.
+ *
+ * @author wil
+ */
+final class Win32GLPlatform extends PlatformWin32GLCanvas implements LwjglxGLPlatform {
+
+ /**
+ * (non-Javadoc)
+ * @see com.jme3.system.lwjglx.LwjglxGLPlatform#destroy()
+ */
+ @Override
+ public void destroy() {
+ if (ds != null) {
+ JAWT_FreeDrawingSurface(ds, awt.FreeDrawingSurface());
+ awt.free();
+ }
+ }
+}
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
new file mode 100644
index 0000000000..198b9b7317
--- /dev/null
+++ b/jme3-lwjgl3/src/main/java/com/jme3/system/lwjglx/X11GLPlatform.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2009-2023 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.PlatformLinuxGLCanvas;
+import org.lwjgl.system.jawt.*;
+
+import static org.lwjgl.system.MemoryUtil.*;
+import static org.lwjgl.system.jawt.JAWTFunctions.*;
+
+/**
+ * Class X11GLPlatform
; overrides the following methods: swapBuffers()
+ * and makeCurrent(long context)
. So that the canvas can be removed and
+ * added back from its parent component.
+ *
+ *
+ * Works only for Linux based platforms + * + * @author wil + */ +final class X11GLPlatform extends PlatformLinuxGLCanvas implements LwjglxGLPlatform { + + /** + * (non-Javadoc) + * @see org.lwjgl.opengl.awt.PlatformGLCanvas#swapBuffers() + * @return boolean + */ + @Override + public boolean swapBuffers() { + // Get the drawing surface info + JAWTDrawingSurfaceInfo dsi = JAWT_DrawingSurface_GetDrawingSurfaceInfo(ds, ds.GetDrawingSurfaceInfo()); + if (dsi == null) { + throw new IllegalStateException("JAWT_DrawingSurface_GetDrawingSurfaceInfo() failed"); + } + + try { + // Get the platform-specific drawing info + JAWTX11DrawingSurfaceInfo dsi_x11 = JAWTX11DrawingSurfaceInfo.create(dsi.platformInfo()); + + // Set new values + display = dsi_x11.display(); + drawable = dsi_x11.drawable(); + + // Swap-Buffers + return super.swapBuffers(); + } finally { + JAWT_DrawingSurface_FreeDrawingSurfaceInfo(dsi, ds.FreeDrawingSurfaceInfo()); + } + } + + /** + * (non-Javadoc) + * @see org.lwjgl.opengl.awt.PlatformGLCanvas#makeCurrent(long) + * + * @param context long + * @return boolean + */ + @Override + public boolean makeCurrent(long context) { + // Get the drawing surface info + JAWTDrawingSurfaceInfo dsi = JAWT_DrawingSurface_GetDrawingSurfaceInfo(ds, ds.GetDrawingSurfaceInfo()); + if (dsi == null) { + throw new IllegalStateException("JAWT_DrawingSurface_GetDrawingSurfaceInfo() failed"); + } + + try { + // Get the platform-specific drawing info + JAWTX11DrawingSurfaceInfo dsi_x11 = JAWTX11DrawingSurfaceInfo.create(dsi.platformInfo()); + + // Set new values + display = dsi_x11.display(); + drawable = dsi_x11.drawable(); + + if (drawable == NULL) { + return false; + } + return super.makeCurrent(context); + } finally { + JAWT_DrawingSurface_FreeDrawingSurfaceInfo(dsi, ds.FreeDrawingSurfaceInfo()); + } + } + + /** + * (non-Javadoc) + * @see com.jme3.system.lwjglx.LwjglxGLPlatform#destroy() + */ + @Override + public void destroy() { + if (ds != null) { + JAWT_FreeDrawingSurface(ds, awt.FreeDrawingSurface()); + awt.free(); + } + } +} diff --git a/jme3-lwjgl3/src/main/java/com/jme3/util/LWJGLBufferAllocator.java b/jme3-lwjgl3/src/main/java/com/jme3/util/LWJGLBufferAllocator.java index c406da86de..77e6330696 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/util/LWJGLBufferAllocator.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/util/LWJGLBufferAllocator.java @@ -8,6 +8,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.StampedLock; +import java.util.logging.Level; import java.util.logging.Logger; /** @@ -164,7 +165,7 @@ public void destroyDirectBuffer(final Buffer buffer) { final long address = getAddress(buffer); if (address == -1) { - LOGGER.warning("Not found address of the " + buffer); + LOGGER.log(Level.WARNING, "Not found address of the {0}", buffer); return; } @@ -172,7 +173,7 @@ public void destroyDirectBuffer(final Buffer buffer) { final Deallocator deallocator = DEALLOCATORS.remove(address); if (deallocator == null) { - LOGGER.warning("Not found a deallocator for address " + address); + LOGGER.log(Level.WARNING, "Not found a deallocator for address {0}", address); return; }