|
|
|
@ -33,11 +33,11 @@ |
|
|
|
|
package com.jme3.system.jogl; |
|
|
|
|
|
|
|
|
|
import com.jme3.system.AppSettings; |
|
|
|
|
import java.awt.BorderLayout; |
|
|
|
|
import java.awt.Container; |
|
|
|
|
import java.awt.Dimension; |
|
|
|
|
import java.awt.DisplayMode; |
|
|
|
|
import java.awt.Frame; |
|
|
|
|
import java.awt.GraphicsDevice; |
|
|
|
|
import java.awt.GraphicsEnvironment; |
|
|
|
|
import java.awt.Toolkit; |
|
|
|
|
import java.awt.event.WindowAdapter; |
|
|
|
|
import java.awt.event.WindowEvent; |
|
|
|
@ -46,6 +46,7 @@ import java.util.concurrent.atomic.AtomicBoolean; |
|
|
|
|
import java.util.logging.Level; |
|
|
|
|
import java.util.logging.Logger; |
|
|
|
|
import javax.media.opengl.GLAutoDrawable; |
|
|
|
|
import javax.media.opengl.GLContext; |
|
|
|
|
import javax.swing.JFrame; |
|
|
|
|
import javax.swing.SwingUtilities; |
|
|
|
|
|
|
|
|
@ -56,14 +57,14 @@ public class JoglDisplay extends JoglAbstractDisplay { |
|
|
|
|
protected AtomicBoolean windowCloseRequest = new AtomicBoolean(false); |
|
|
|
|
protected AtomicBoolean needClose = new AtomicBoolean(false); |
|
|
|
|
protected AtomicBoolean needRestart = new AtomicBoolean(false); |
|
|
|
|
protected boolean wasInited = false; |
|
|
|
|
protected volatile boolean wasInited = false; |
|
|
|
|
protected Frame frame; |
|
|
|
|
|
|
|
|
|
public Type getType() { |
|
|
|
|
return Type.Display; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected DisplayMode getFullscreenDisplayMode(DisplayMode[] modes, int width, int height, int bpp, int freq){ |
|
|
|
|
/*protected DisplayMode getFullscreenDisplayMode(DisplayMode[] modes, int width, int height, int bpp, int freq){ |
|
|
|
|
for (DisplayMode mode : modes){ |
|
|
|
|
if (mode.getWidth() == width |
|
|
|
|
&& mode.getHeight() == height |
|
|
|
@ -75,43 +76,34 @@ public class JoglDisplay extends JoglAbstractDisplay { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
protected void createGLFrame(){ |
|
|
|
|
Container contentPane; |
|
|
|
|
//Container contentPane;
|
|
|
|
|
if (useAwt){ |
|
|
|
|
frame = new Frame(settings.getTitle()); |
|
|
|
|
contentPane = frame; |
|
|
|
|
//contentPane = frame;
|
|
|
|
|
}else{ |
|
|
|
|
frame = new JFrame(settings.getTitle()); |
|
|
|
|
contentPane = ((JFrame)frame).getContentPane(); |
|
|
|
|
//contentPane = ((JFrame)frame).getContentPane();
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
contentPane.setLayout(new BorderLayout()); |
|
|
|
|
|
|
|
|
|
applySettings(settings); |
|
|
|
|
|
|
|
|
|
frame.setResizable(false); |
|
|
|
|
frame.setFocusable(true); |
|
|
|
|
|
|
|
|
|
// only add canvas after frame is visible
|
|
|
|
|
contentPane.add(canvas, BorderLayout.CENTER); |
|
|
|
|
//frame.pack();
|
|
|
|
|
// frame.setSize(contentPane.getPreferredSize());
|
|
|
|
|
frame.setSize(settings.getWidth(),settings.getHeight()); |
|
|
|
|
|
|
|
|
|
if (device.getFullScreenWindow() == null){ |
|
|
|
|
// now that canvas is attached,
|
|
|
|
|
// determine optimal size to contain it
|
|
|
|
|
|
|
|
|
|
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
|
|
|
|
frame.setLocation((screenSize.width - frame.getWidth()) / 2, |
|
|
|
|
(screenSize.height - frame.getHeight()) / 2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
frame.add(canvas); |
|
|
|
|
//frame.validate();
|
|
|
|
|
|
|
|
|
|
applySettings(settings); |
|
|
|
|
|
|
|
|
|
frame.addWindowListener(new WindowAdapter() { |
|
|
|
|
@Override |
|
|
|
|
public void windowClosing(WindowEvent evt) { |
|
|
|
|
// If required, restore the previous display mode
|
|
|
|
|
/*if (isDisplayModeModified) { |
|
|
|
|
gd.setDisplayMode(previousDisplayMode); |
|
|
|
|
} |
|
|
|
|
// If required, get back to the windowed mode
|
|
|
|
|
if (gd.getFullScreenWindow() == frame) { |
|
|
|
|
gd.setFullScreenWindow(null); |
|
|
|
|
}*/ |
|
|
|
|
windowCloseRequest.set(true); |
|
|
|
|
} |
|
|
|
|
@Override |
|
|
|
@ -124,65 +116,136 @@ public class JoglDisplay extends JoglAbstractDisplay { |
|
|
|
|
active.set(false); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// Make the window visible to realize the OpenGL surface.
|
|
|
|
|
frame.setVisible(true); |
|
|
|
|
|
|
|
|
|
canvas.setVisible(true); |
|
|
|
|
|
|
|
|
|
final GLContext context = canvas.getContext(); |
|
|
|
|
|
|
|
|
|
/*canvas.invoke(true, new GLRunnable() { |
|
|
|
|
@Override |
|
|
|
|
public boolean run(GLAutoDrawable glAutoDrawable) { |
|
|
|
|
context.makeCurrent(); |
|
|
|
|
try { |
|
|
|
|
startGLCanvas(); |
|
|
|
|
} |
|
|
|
|
finally { |
|
|
|
|
context.release(); |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
});*/ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected void applySettings(AppSettings settings){ |
|
|
|
|
DisplayMode displayMode; |
|
|
|
|
if (settings.getWidth() <= 0 || settings.getHeight() <= 0){ |
|
|
|
|
displayMode = device.getDisplayMode(); |
|
|
|
|
settings.setResolution(displayMode.getWidth(), displayMode.getHeight()); |
|
|
|
|
}else if (settings.isFullscreen()){ |
|
|
|
|
displayMode = getFullscreenDisplayMode(device.getDisplayModes(), |
|
|
|
|
settings.getWidth(), settings.getHeight(), |
|
|
|
|
settings.getBitsPerPixel(), settings.getFrequency()); |
|
|
|
|
if (displayMode == null) |
|
|
|
|
throw new RuntimeException("Unable to find fullscreen display mode matching settings"); |
|
|
|
|
}else{ |
|
|
|
|
displayMode = new DisplayMode(settings.getWidth(), settings.getHeight(), DisplayMode.BIT_DEPTH_MULTI, DisplayMode.REFRESH_RATE_UNKNOWN); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// FIXME: seems to return false even though
|
|
|
|
|
// it is supported..
|
|
|
|
|
// if (!device.isDisplayChangeSupported()){
|
|
|
|
|
// // must use current device mode if display mode change not supported
|
|
|
|
|
// displayMode = device.getDisplayMode();
|
|
|
|
|
// settings.setResolution(displayMode.getWidth(), displayMode.getHeight());
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
frameRate = settings.getFrameRate(); |
|
|
|
|
logger.log(Level.INFO, "Selected display mode: {0}x{1}x{2} @{3}", |
|
|
|
|
new Object[]{displayMode.getWidth(), |
|
|
|
|
displayMode.getHeight(), |
|
|
|
|
displayMode.getBitDepth(), |
|
|
|
|
displayMode.getRefreshRate()}); |
|
|
|
|
|
|
|
|
|
canvas.setSize(displayMode.getWidth(), displayMode.getHeight()); |
|
|
|
|
|
|
|
|
|
DisplayMode prevDisplayMode = device.getDisplayMode(); |
|
|
|
|
|
|
|
|
|
if (settings.isFullscreen() && device.isFullScreenSupported()){ |
|
|
|
|
final boolean isDisplayModeModified; |
|
|
|
|
final GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); |
|
|
|
|
// Get the current display mode
|
|
|
|
|
final DisplayMode previousDisplayMode = gd.getDisplayMode(); |
|
|
|
|
// Handle full screen mode if requested.
|
|
|
|
|
if (settings.isFullscreen()) { |
|
|
|
|
frame.setUndecorated(true); |
|
|
|
|
|
|
|
|
|
try{ |
|
|
|
|
device.setFullScreenWindow(frame); |
|
|
|
|
if (!prevDisplayMode.equals(displayMode) |
|
|
|
|
&& device.isDisplayChangeSupported()){ |
|
|
|
|
device.setDisplayMode(displayMode); |
|
|
|
|
// Check if the full-screen mode is supported by the OS
|
|
|
|
|
boolean isFullScreenSupported = gd.isFullScreenSupported(); |
|
|
|
|
if (isFullScreenSupported) { |
|
|
|
|
gd.setFullScreenWindow(frame); |
|
|
|
|
// Check if display mode changes are supported by the OS
|
|
|
|
|
if (gd.isDisplayChangeSupported()) { |
|
|
|
|
// Get all available display modes
|
|
|
|
|
final DisplayMode[] displayModes = gd.getDisplayModes(); |
|
|
|
|
DisplayMode multiBitsDepthSupportedDisplayMode = null; |
|
|
|
|
DisplayMode refreshRateUnknownDisplayMode = null; |
|
|
|
|
DisplayMode multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode = null; |
|
|
|
|
DisplayMode matchingDisplayMode = null; |
|
|
|
|
DisplayMode currentDisplayMode; |
|
|
|
|
// Look for the display mode that matches with our parameters
|
|
|
|
|
// Look for some display modes that are close to these parameters
|
|
|
|
|
// and that could be used as substitutes
|
|
|
|
|
// On some machines, the refresh rate is unknown and/or multi bit
|
|
|
|
|
// depths are supported. If you try to force a particular refresh
|
|
|
|
|
// rate or a bit depth, you might find no available display mode
|
|
|
|
|
// that matches exactly with your parameters
|
|
|
|
|
for (int i = 0; i < displayModes.length && matchingDisplayMode == null; i++) { |
|
|
|
|
currentDisplayMode = displayModes[i]; |
|
|
|
|
if (currentDisplayMode.getWidth() == settings.getWidth() |
|
|
|
|
&& currentDisplayMode.getHeight() == settings.getHeight()) { |
|
|
|
|
if (currentDisplayMode.getBitDepth() == settings.getBitsPerPixel()) { |
|
|
|
|
if (currentDisplayMode.getRefreshRate() == settings.getFrequency()) { |
|
|
|
|
matchingDisplayMode = currentDisplayMode; |
|
|
|
|
} else if (currentDisplayMode.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN) { |
|
|
|
|
refreshRateUnknownDisplayMode = currentDisplayMode; |
|
|
|
|
} |
|
|
|
|
} else if (currentDisplayMode.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) { |
|
|
|
|
if (currentDisplayMode.getRefreshRate() == settings.getFrequency()) { |
|
|
|
|
multiBitsDepthSupportedDisplayMode = currentDisplayMode; |
|
|
|
|
} else if (currentDisplayMode.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN) { |
|
|
|
|
multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode = currentDisplayMode; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
DisplayMode nextDisplayMode = null; |
|
|
|
|
if (matchingDisplayMode != null) { |
|
|
|
|
nextDisplayMode = matchingDisplayMode; |
|
|
|
|
} else if (multiBitsDepthSupportedDisplayMode != null) { |
|
|
|
|
nextDisplayMode = multiBitsDepthSupportedDisplayMode; |
|
|
|
|
} else if (refreshRateUnknownDisplayMode != null) { |
|
|
|
|
nextDisplayMode = refreshRateUnknownDisplayMode; |
|
|
|
|
} else if (multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode != null) { |
|
|
|
|
nextDisplayMode = multiBitsDepthSupportedAndRefreshRateUnknownDisplayMode; |
|
|
|
|
} else { |
|
|
|
|
isFullScreenSupported = false; |
|
|
|
|
} |
|
|
|
|
// If we have found a display mode that approximatively matches
|
|
|
|
|
// with the input parameters, use it
|
|
|
|
|
if (nextDisplayMode != null) { |
|
|
|
|
gd.setDisplayMode(nextDisplayMode); |
|
|
|
|
isDisplayModeModified = true; |
|
|
|
|
} else { |
|
|
|
|
isDisplayModeModified = false; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
isDisplayModeModified = false; |
|
|
|
|
// Resize the canvas if the display mode cannot be changed
|
|
|
|
|
// and the screen size is not equal to the canvas size
|
|
|
|
|
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
|
|
|
|
if (screenSize.width != settings.getWidth() || screenSize.height != settings.getHeight()) { |
|
|
|
|
canvas.setSize(screenSize); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} catch (Throwable t){ |
|
|
|
|
logger.log(Level.SEVERE, "Failed to enter fullscreen mode", t); |
|
|
|
|
device.setFullScreenWindow(null); |
|
|
|
|
} |
|
|
|
|
}else{ |
|
|
|
|
if (!device.isFullScreenSupported()){ |
|
|
|
|
logger.warning("Fullscreen not supported."); |
|
|
|
|
}else{ |
|
|
|
|
frame.setUndecorated(false); |
|
|
|
|
device.setFullScreenWindow(null); |
|
|
|
|
} else { |
|
|
|
|
isDisplayModeModified = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
frame.setVisible(true); |
|
|
|
|
// Software windowed full-screen mode
|
|
|
|
|
if (!isFullScreenSupported) { |
|
|
|
|
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
|
|
|
|
// Resize the canvas
|
|
|
|
|
canvas.setSize(screenSize); |
|
|
|
|
// Resize the frame so that it occupies the whole screen
|
|
|
|
|
frame.setSize(screenSize); |
|
|
|
|
// Set its location at the top left corner
|
|
|
|
|
frame.setLocation(0, 0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Otherwise, center the window on the screen.
|
|
|
|
|
else { |
|
|
|
|
isDisplayModeModified = false; |
|
|
|
|
frame.pack(); |
|
|
|
|
|
|
|
|
|
int x, y; |
|
|
|
|
x = (Toolkit.getDefaultToolkit().getScreenSize().width - settings.getWidth()) / 2; |
|
|
|
|
y = (Toolkit.getDefaultToolkit().getScreenSize().height - settings.getHeight()) / 2; |
|
|
|
|
frame.setLocation(x, y); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
logger.log(Level.INFO, "Selected display mode: {0}x{1}x{2} @{3}", |
|
|
|
|
new Object[]{frame.getWidth(), |
|
|
|
|
frame.getHeight(), |
|
|
|
|
0, |
|
|
|
|
0}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void initInEDT(){ |
|
|
|
|