OSDN Git Service

ran gdx-tools HeaderFixer tool
[mikumikustudio/libgdx-mikumikustudio.git] / backends / gdx-backend-jglfw / src / com / badlogic / gdx / backends / jglfw / JglfwGraphics.java
index c1c1912..56117e3 100644 (file)
@@ -1,20 +1,36 @@
+/*******************************************************************************\r
+ * Copyright 2011 See AUTHORS file.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *   http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ ******************************************************************************/
 
 package com.badlogic.gdx.backends.jglfw;
 
 import static com.badlogic.jglfw.Glfw.*;
 
+import com.badlogic.gdx.ApplicationListener;
 import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.Graphics;
+import com.badlogic.gdx.graphics.Color;
 import com.badlogic.gdx.graphics.GL10;
 import com.badlogic.gdx.graphics.GL11;
 import com.badlogic.gdx.graphics.GL20;
 import com.badlogic.gdx.graphics.GLCommon;
 import com.badlogic.gdx.utils.Array;
 import com.badlogic.gdx.utils.GdxRuntimeException;
+import com.badlogic.jglfw.GlfwVideoMode;
 import com.badlogic.jglfw.gl.GL;
 
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
 import java.awt.Toolkit;
 
 /** An implementation of the {@link Graphics} interface based on GLFW.
@@ -22,97 +38,145 @@ import java.awt.Toolkit;
 public class JglfwGraphics implements Graphics {
        static int glMajorVersion, glMinorVersion;
 
-       JglfwApplicationConfiguration config;
        long window;
-       boolean fullscreen;
-       int fullscreenMonitorIndex;
-       final BufferFormat bufferFormat;
-       volatile boolean isContinuous = true;
-
-       float deltaTime;
-       long frameStart, lastTime;
-       int frames, fps;
-
-       GLCommon gl;
-       JglfwGL10 gl10;
-       JglfwGL11 gl11;
-       JglfwGL20 gl20;
-
-       boolean sync;
-       boolean resize;
-       volatile boolean requestRendering;
+       private boolean fullscreen;
+       private long fullscreenMonitor;
+       private String title;
+       private boolean resizable, undecorated;
+       private BufferFormat bufferFormat;
+       private boolean vSync;
+       private int x, y, width, height;
+       private boolean visible;
+       private Color initialBackgroundColor;
+       private volatile boolean isContinuous = true, renderRequested;
+       volatile boolean foreground, minimized;
+
+       private float deltaTime;
+       private long frameStart, lastTime = -1;
+       private int frames, fps;
+
+       private GLCommon gl;
+       private JglfwGL10 gl10;
+       private JglfwGL11 gl11;
+       private JglfwGL20 gl20;
 
        public JglfwGraphics (JglfwApplicationConfiguration config) {
-               this.config = config;
-
+               // Store values from config.
                bufferFormat = new BufferFormat(config.r, config.g, config.b, config.a, config.depth, config.stencil, config.samples, false);
-
-               createWindow();
-               createGL();
-       }
-
-       private void createWindow () {
-               glfwWindowHint(GLFW_RESIZABLE, config.resizable ? 1 : 0);
-               glfwWindowHint(GLFW_RED_BITS, config.r);
-               glfwWindowHint(GLFW_GREEN_BITS, config.g);
-               glfwWindowHint(GLFW_BLUE_BITS, config.b);
-               glfwWindowHint(GLFW_ALPHA_BITS, config.a);
-               glfwWindowHint(GLFW_DEPTH_BITS, config.depth);
-               glfwWindowHint(GLFW_STENCIL_BITS, config.stencil);
-               glfwWindowHint(GLFW_SAMPLES, config.samples);
-               glfwWindowHint(GLFW_DEPTH_BITS, config.bitsPerPixel);
-
-               long fullscreenMonitor = glfwGetPrimaryMonitor();
-               long[] monitors = glfwGetMonitors();
-               // Find index of primary monitor.
-               for (int i = 0, n = monitors.length; i < n; i++) {
-                       if (monitors[i] == fullscreenMonitor) {
-                               fullscreenMonitorIndex = i;
-                               break;
-                       }
-               }
-               // Find monitor specified in config.
-               if (config.fullscreen) {
-                       if (monitors.length > 0) {
-                               if (config.fullscreenMonitorIndex < monitors.length) fullscreenMonitorIndex = config.fullscreenMonitorIndex;
-                               fullscreenMonitor = monitors[fullscreenMonitorIndex];
-                       }
+               title = config.title;
+               resizable = config.resizable;
+               undecorated = config.undecorated;
+               x = config.x;
+               y = config.y;
+               vSync = config.vSync;
+               initialBackgroundColor = config.initialBackgroundColor;
+               if (config.fullscreenMonitorIndex != -1) { // Use monitor specified in config if it is valid.
+                       long[] monitors = glfwGetMonitors();
+                       if (config.fullscreenMonitorIndex < monitors.length) fullscreenMonitor = monitors[config.fullscreenMonitorIndex];
                }
 
                // Create window.
-               if (!setDisplayMode(config.width, config.height, config.fullscreen)) {
+               if (!createWindow(config.width, config.height, config.fullscreen)) {
                        throw new GdxRuntimeException("Unable to create window: " + config.width + "x" + config.height + ", fullscreen: "
                                + config.fullscreen);
                }
 
-               setVSync(config.vSync);
-               if (config.x != -1 && config.y != -1) glfwSetWindowPos(window, config.x, config.y);
-       }
-
-       private void createGL () {
+               // Create GL.
                String version = GL.glGetString(GL11.GL_VERSION);
                glMajorVersion = Integer.parseInt("" + version.charAt(0));
                glMinorVersion = Integer.parseInt("" + version.charAt(2));
-
                if (config.useGL20 && (glMajorVersion >= 2 || version.contains("2.1"))) { // special case for MESA, wtf...
-                       // FIXME - Add check whether gl 2.0 is actually supported.
                        gl20 = new JglfwGL20();
                        gl = gl20;
                } else {
                        gl20 = null;
-                       if (glMajorVersion == 1 && glMinorVersion < 5) {
+                       if (glMajorVersion == 1 && glMinorVersion < 5)
                                gl10 = new JglfwGL10();
-                       else {
+                       else {
                                gl11 = new JglfwGL11();
                                gl10 = gl11;
                        }
                        gl = gl10;
                }
-
                Gdx.gl = gl;
                Gdx.gl10 = gl10;
                Gdx.gl11 = gl11;
                Gdx.gl20 = gl20;
+
+               if (!config.hidden) show();
+       }
+
+       private boolean createWindow (int width, int height, boolean fullscreen) {
+               if (fullscreen && fullscreenMonitor == 0) fullscreenMonitor = getWindowMonitor();
+
+               glfwWindowHint(GLFW_VISIBLE, 0);
+               glfwWindowHint(GLFW_RESIZABLE, resizable ? 1 : 0);
+               glfwWindowHint(GLFW_UNDECORATED, undecorated ? 1 : 0);
+               glfwWindowHint(GLFW_RED_BITS, bufferFormat.r);
+               glfwWindowHint(GLFW_GREEN_BITS, bufferFormat.g);
+               glfwWindowHint(GLFW_BLUE_BITS, bufferFormat.b);
+               glfwWindowHint(GLFW_ALPHA_BITS, bufferFormat.a);
+               glfwWindowHint(GLFW_DEPTH_BITS, bufferFormat.depth);
+               glfwWindowHint(GLFW_STENCIL_BITS, bufferFormat.stencil);
+               glfwWindowHint(GLFW_SAMPLES, bufferFormat.samples);
+
+               boolean mouseCaptured = window != 0 && glfwGetInputMode(window, GLFW_CURSOR_MODE) == GLFW_CURSOR_CAPTURED;
+
+               long oldWindow = window;
+               long newWindow = glfwCreateWindow(width, height, title, fullscreen ? fullscreenMonitor : 0, oldWindow);
+               if (newWindow == 0) return false;
+               if (oldWindow != 0) glfwDestroyWindow(oldWindow);
+               window = newWindow;
+               this.width = Math.max(1, width);
+               this.height = Math.max(1, height);
+
+               this.fullscreen = fullscreen;
+               if (!fullscreen) {
+                       if (x == -1 || y == -1) {
+                               DisplayMode mode = getDesktopDisplayMode();
+                               x = (mode.width - width) / 2;
+                               y = (mode.height - height) / 2;
+                       }
+                       glfwSetWindowPos(window, x, y);
+               }
+
+               if (!mouseCaptured) glfwSetInputMode(window, GLFW_CURSOR_MODE, GLFW_CURSOR_NORMAL); // Prevent fullscreen from taking mouse.
+
+               glfwMakeContextCurrent(newWindow);
+               setVSync(vSync);
+               if (visible) glfwShowWindow(window);
+
+               return true;
+       }
+
+       void frameStart (long time) {
+               if (lastTime == -1) lastTime = time;
+               deltaTime = (time - lastTime) / 1000000000.0f;
+               lastTime = time;
+
+               if (time - frameStart >= 1000000000) {
+                       fps = frames;
+                       frames = 0;
+                       frameStart = time;
+               }
+               frames++;
+       }
+
+       void sizeChanged (int width, int height) {
+               glfwShowWindow(window); // This is required to refresh the NSOpenGLContext on OSX!
+               width = Math.max(1, width);
+               height = Math.max(1, height);
+               this.width = width;
+               this.height = height;
+               Gdx.gl.glViewport(0, 0, width, height);
+               ApplicationListener listener = Gdx.app.getApplicationListener();
+               if (listener != null) listener.resize(width, height);
+               requestRendering();
+       }
+
+       void positionChanged (int x, int y) {
+               this.x = x;
+               this.y = y;
        }
 
        public boolean isGL11Available () {
@@ -140,24 +204,11 @@ public class JglfwGraphics implements Graphics {
        }
 
        public int getWidth () {
-               return glfwGetWindowWidth(window);
+               return width;
        }
 
        public int getHeight () {
-               return glfwGetWindowHeight(window);
-       }
-
-       void updateTime () {
-               long time = System.nanoTime();
-               deltaTime = (time - lastTime) / 1000000000.0f;
-               lastTime = time;
-
-               if (time - frameStart >= 1000000000) {
-                       fps = frames;
-                       frames = 0;
-                       frameStart = time;
-               }
-               frames++;
+               return height;
        }
 
        public float getDeltaTime () {
@@ -177,22 +228,35 @@ public class JglfwGraphics implements Graphics {
        }
 
        public float getPpiX () {
+               // return getWidth() / (glfwGetMonitorPhysicalWidth(getWindowMonitor()) * 0.03937f); // mm to inches
                return Toolkit.getDefaultToolkit().getScreenResolution();
        }
 
        public float getPpiY () {
+               // return getHeight() / (glfwGetMonitorPhysicalHeight(getWindowMonitor()) * 0.03937f); // mm to inches
                return Toolkit.getDefaultToolkit().getScreenResolution();
        }
 
        public float getPpcX () {
+               // return getWidth() / (glfwGetMonitorPhysicalWidth(getWindowMonitor()) / 10); // mm to cm
                return Toolkit.getDefaultToolkit().getScreenResolution() / 2.54f;
        }
 
        public float getPpcY () {
+               // return getHeight() / (glfwGetMonitorPhysicalHeight(getWindowMonitor()) / 10); // mm to cm
                return Toolkit.getDefaultToolkit().getScreenResolution() / 2.54f;
        }
 
        public float getDensity () {
+               // long monitor = getWindowMonitor();
+               // float mmWidth = glfwGetMonitorPhysicalWidth(monitor);
+               // float mmHeight = glfwGetMonitorPhysicalHeight(monitor);
+               // float inches = (float)Math.sqrt(mmWidth * mmWidth + mmHeight * mmHeight) * 0.03937f; // mm to inches
+               // float pixelWidth = getWidth();
+               // float pixelHeight = getHeight();
+               // float pixels = (float)Math.sqrt(pixelWidth * pixelWidth + pixelHeight * pixelHeight);
+               // float diagonalPpi = pixels / inches;
+               // return diagonalPpi / 160f;
                return Toolkit.getDefaultToolkit().getScreenResolution() / 160f;
        }
 
@@ -200,58 +264,57 @@ public class JglfwGraphics implements Graphics {
                return true;
        }
 
+       private long getWindowMonitor () {
+               if (window != 0) {
+                       long monitor = glfwGetWindowMonitor(window);
+                       if (monitor != 0) return monitor;
+               }
+               return glfwGetPrimaryMonitor();
+       }
+
        public DisplayMode[] getDisplayModes () {
-               GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
-               java.awt.DisplayMode desktopMode = device.getDisplayMode();
-               java.awt.DisplayMode[] displayModes = device.getDisplayModes();
                Array<DisplayMode> modes = new Array();
-               outer:
-               for (java.awt.DisplayMode mode : displayModes) {
-                       for (DisplayMode other : modes)
-                               if (other.width == mode.getWidth() && other.height == mode.getHeight() && other.bitsPerPixel == mode.getBitDepth())
-                                       continue outer; // Duplicate.
-                       if (mode.getBitDepth() != desktopMode.getBitDepth()) continue;
-                       modes.add(new JglfwDisplayMode(mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getBitDepth()));
-               }
-               return modes.toArray();
+               for (GlfwVideoMode mode : glfwGetVideoModes(getWindowMonitor()))
+                       modes.add(new JglfwDisplayMode(mode.width, mode.height, 0, mode.redBits + mode.greenBits + mode.blueBits));
+               return modes.toArray(DisplayMode.class);
        }
 
        public DisplayMode getDesktopDisplayMode () {
-               java.awt.DisplayMode mode = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode();
-               return new JglfwDisplayMode(mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getBitDepth());
+               GlfwVideoMode mode = glfwGetVideoMode(getWindowMonitor());
+               return new JglfwDisplayMode(mode.width, mode.height, 0, mode.redBits + mode.greenBits + mode.blueBits);
        }
 
        public boolean setDisplayMode (DisplayMode displayMode) {
-               if (displayMode.bitsPerPixel != 0) glfwWindowHint(GLFW_DEPTH_BITS, displayMode.bitsPerPixel);
-               glfwSetWindowSize(window, displayMode.width, displayMode.height);
-               return true;
+               bufferFormat = new BufferFormat( //
+                       displayMode.bitsPerPixel == 16 ? 5 : 8, //
+                       displayMode.bitsPerPixel == 16 ? 6 : 8, //
+                       displayMode.bitsPerPixel == 16 ? 6 : 8, //
+                       bufferFormat.a, bufferFormat.depth, bufferFormat.stencil, bufferFormat.samples, false);
+               boolean success = createWindow(displayMode.width, displayMode.height, fullscreen);
+               if (success && fullscreen) sizeChanged(displayMode.width, displayMode.height);
+               return success;
        }
 
        public boolean setDisplayMode (int width, int height, boolean fullscreen) {
-               if (window == 0 || fullscreen != config.fullscreen) {
-                       long fullscreenMonitor = 0;
-                       long[] monitors = glfwGetMonitors();
-                       if (monitors.length > 0)
-                               fullscreenMonitor = fullscreenMonitorIndex < monitors.length ? monitors[fullscreenMonitorIndex] : 0;
-
-                       long window = glfwCreateWindow(config.width, config.height, config.title, fullscreenMonitor, 0);
-                       if (window == 0) return false;
-                       if (this.window != 0) glfwDestroyWindow(window);
-                       glfwMakeContextCurrent(window);
-                       this.window = window;
-                       return true;
+               if (fullscreen || this.fullscreen) {
+                       boolean success = createWindow(width, height, fullscreen);
+                       if (success && fullscreen) sizeChanged(width, height);
+                       return success;
                }
+
                glfwSetWindowSize(window, width, height);
                return true;
        }
 
        public void setTitle (String title) {
+               if (title == null) title = "";
                glfwSetWindowTitle(window, title);
+               this.title = title;
        }
 
        public void setVSync (boolean vsync) {
-               this.sync = vsync;
-               if (!config.cpuSync) glfwSwapInterval(vsync ? 1 : 0);
+               this.vSync = vsync;
+               glfwSwapInterval(vsync ? 1 : 0);
        }
 
        public BufferFormat getBufferFormat () {
@@ -271,13 +334,11 @@ public class JglfwGraphics implements Graphics {
        }
 
        public void requestRendering () {
-               synchronized (this) {
-                       requestRendering = true;
-               }
+               renderRequested = true;
        }
 
        public boolean isFullscreen () {
-               return config.fullscreen;
+               return fullscreen;
        }
 
        /** Returns the JGLFW window handle. Note this should not be stored externally as it may change if the window is recreated to
@@ -286,11 +347,57 @@ public class JglfwGraphics implements Graphics {
                return window;
        }
 
+       public int getX () {
+               return x;
+       }
+
+       public int getY () {
+               return y;
+       }
+
+       public void setPosition (int x, int y) {
+               glfwSetWindowPos(window, x, y);
+       }
+
+       public void hide () {
+               visible = false;
+               glfwHideWindow(window);
+       }
+
+       public void show () {
+               visible = true;
+               glfwShowWindow(window);
+
+               Gdx.gl.glClearColor(initialBackgroundColor.r, initialBackgroundColor.g, initialBackgroundColor.b, initialBackgroundColor.a);
+               Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
+               glfwSwapBuffers(window);
+       }
+
+       public boolean isHidden () {
+               return !visible;
+       }
+
+       public boolean isMinimized () {
+               return minimized;
+       }
+
+       public boolean isForeground () {
+               return foreground;
+       }
+
+       public void minimize () {
+               glfwIconifyWindow(window);
+       }
+
+       public void restore () {
+               glfwRestoreWindow(window);
+       }
+
        boolean shouldRender () {
-               synchronized (this) {
-                       boolean requestRendering = this.requestRendering;
-                       this.requestRendering = false;
-                       return requestRendering || isContinuous;
+               try {
+                       return renderRequested || isContinuous;
+               } finally {
+                       renderRequested = false;
                }
        }
 
@@ -299,4 +406,4 @@ public class JglfwGraphics implements Graphics {
                        super(width, height, refreshRate, bitsPerPixel);
                }
        }
-}
+}
\ No newline at end of file