Quellcode durchsuchen

Sets the input sources to avoid throwing a NullPointerException and sets the proper size to the canvas

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9893 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
jul..om vor 13 Jahren
Ursprung
Commit
965b595384

+ 16 - 6
engine/src/jogl/com/jme3/system/jogl/JoglAbstractDisplay.java

@@ -77,7 +77,7 @@ public abstract class JoglAbstractDisplay extends JoglContext implements GLEvent
         device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
 
         GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
-        caps.setHardwareAccelerated(true);
+        /*caps.setHardwareAccelerated(true);
         caps.setDoubleBuffered(true);
         caps.setStencilBits(settings.getStencilBits());
         caps.setDepthBits(settings.getDepthBits());
@@ -85,7 +85,7 @@ public abstract class JoglAbstractDisplay extends JoglContext implements GLEvent
         if (settings.getSamples() > 1) {
             caps.setSampleBuffers(true);
             caps.setNumSamples(settings.getSamples());
-        }
+        }*/
 
         canvas = new GLCanvas(caps) {
             @Override
@@ -105,9 +105,14 @@ public abstract class JoglAbstractDisplay extends JoglContext implements GLEvent
             canvas.getGL().setSwapInterval(1);
         }
         canvas.setFocusable(true);
+        canvas.requestFocus();
+        canvas.setSize(settings.getWidth(), settings.getHeight());
         canvas.setIgnoreRepaint(true);
+        //canvas.setAutoSwapBufferMode(false);
         canvas.addGLEventListener(this);
 
+        
+
         // N.B: it is too early to get the GL instance from the canvas
         // if (false){
         // trace mode
@@ -128,8 +133,9 @@ public abstract class JoglAbstractDisplay extends JoglContext implements GLEvent
             // ((FPSAnimator)animator).setRunAsFastAsPossible(true);
         }
         else {
-            animator = new Animator(canvas);
-            ((Animator) animator).setRunAsFastAsPossible(true);
+            animator = new Animator();
+            animator.add(canvas);
+            //((Animator) animator).setRunAsFastAsPossible(true);
         }
 
         animator.start();
@@ -144,12 +150,16 @@ public abstract class JoglAbstractDisplay extends JoglContext implements GLEvent
 
     @Override
     public KeyInput getKeyInput() {
-        return new AwtKeyInput(/*canvas*/);
+        AwtKeyInput awtKeyInput = new AwtKeyInput();
+        awtKeyInput.setInputSource(canvas);
+        return awtKeyInput;
     }
 
     @Override
     public MouseInput getMouseInput() {
-        return new AwtMouseInput(/*canvas*/);
+        AwtMouseInput awtMouseInput = new AwtMouseInput();
+        awtMouseInput.setInputSource(canvas);
+        return awtMouseInput;
     }
     
     public TouchInput getTouchInput() {

+ 7 - 4
engine/src/jogl/com/jme3/system/jogl/JoglCanvas.java

@@ -97,11 +97,14 @@ public class JoglCanvas extends JoglAbstractDisplay implements JmeCanvasContext
             return;
         }
 
-        if (width != canvas.getWidth() || height != canvas.getHeight()){
-            width = canvas.getWidth();
-            height = canvas.getHeight();
-            if (listener != null)
+        int newWidth = Math.max(canvas.getWidth(), 1);
+        int newHeight = Math.max(canvas.getHeight(), 1);
+        if (width != newWidth || height != newHeight) {
+            width = newWidth;
+            height = newHeight;
+            if (listener != null) {
                 listener.reshape(width, height);
+            }
         }
 
         boolean flush = autoFlush.get();

+ 144 - 81
engine/src/jogl/com/jme3/system/jogl/JoglDisplay.java

@@ -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(){