OSDN Git Service

Merge pull request #277 from DarkIP992/patch-1
[mikumikustudio/libgdx-mikumikustudio.git] / backends / gdx-backend-jglfw / src / com / badlogic / gdx / backends / jglfw / JglfwGraphics.java
1
2 package com.badlogic.gdx.backends.jglfw;
3
4 import static com.badlogic.jglfw.Glfw.*;
5
6 import com.badlogic.gdx.ApplicationListener;
7 import com.badlogic.gdx.Gdx;
8 import com.badlogic.gdx.Graphics;
9 import com.badlogic.gdx.graphics.Color;
10 import com.badlogic.gdx.graphics.GL10;
11 import com.badlogic.gdx.graphics.GL11;
12 import com.badlogic.gdx.graphics.GL20;
13 import com.badlogic.gdx.graphics.GLCommon;
14 import com.badlogic.gdx.utils.Array;
15 import com.badlogic.gdx.utils.GdxRuntimeException;
16 import com.badlogic.jglfw.GlfwVideoMode;
17 import com.badlogic.jglfw.gl.GL;
18
19 import java.awt.Toolkit;
20
21 /** An implementation of the {@link Graphics} interface based on GLFW.
22  * @author Nathan Sweet */
23 public class JglfwGraphics implements Graphics {
24         static int glMajorVersion, glMinorVersion;
25
26         long window;
27         private boolean fullscreen;
28         private long fullscreenMonitor;
29         private String title;
30         private boolean resizable, undecorated;
31         private BufferFormat bufferFormat;
32         private boolean vSync;
33         private int x, y, width, height;
34         private boolean visible;
35         private Color initialBackgroundColor;
36         private volatile boolean isContinuous = true;
37         private volatile boolean renderRequested;
38
39         private float deltaTime;
40         private long frameStart, lastTime = -1;
41         private int frames, fps;
42
43         private GLCommon gl;
44         private JglfwGL10 gl10;
45         private JglfwGL11 gl11;
46         private JglfwGL20 gl20;
47
48         public JglfwGraphics (JglfwApplicationConfiguration config) {
49                 // Store values from config.
50                 bufferFormat = new BufferFormat(config.r, config.g, config.b, config.a, config.depth, config.stencil, config.samples, false);
51                 title = config.title;
52                 resizable = config.resizable;
53                 undecorated = config.undecorated;
54                 x = config.x;
55                 y = config.y;
56                 vSync = config.vSync;
57                 initialBackgroundColor = config.initialBackgroundColor;
58                 if (config.fullscreenMonitorIndex != -1) { // Use monitor specified in config if it is valid.
59                         long[] monitors = glfwGetMonitors();
60                         if (config.fullscreenMonitorIndex < monitors.length) fullscreenMonitor = monitors[config.fullscreenMonitorIndex];
61                 }
62
63                 // Create window.
64                 if (!createWindow(config.width, config.height, config.fullscreen)) {
65                         throw new GdxRuntimeException("Unable to create window: " + config.width + "x" + config.height + ", fullscreen: "
66                                 + config.fullscreen);
67                 }
68
69                 // Create GL.
70                 String version = GL.glGetString(GL11.GL_VERSION);
71                 glMajorVersion = Integer.parseInt("" + version.charAt(0));
72                 glMinorVersion = Integer.parseInt("" + version.charAt(2));
73                 if (config.useGL20 && (glMajorVersion >= 2 || version.contains("2.1"))) { // special case for MESA, wtf...
74                         gl20 = new JglfwGL20();
75                         gl = gl20;
76                 } else {
77                         gl20 = null;
78                         if (glMajorVersion == 1 && glMinorVersion < 5)
79                                 gl10 = new JglfwGL10();
80                         else {
81                                 gl11 = new JglfwGL11();
82                                 gl10 = gl11;
83                         }
84                         gl = gl10;
85                 }
86                 Gdx.gl = gl;
87                 Gdx.gl10 = gl10;
88                 Gdx.gl11 = gl11;
89                 Gdx.gl20 = gl20;
90
91                 if (!config.hidden) show();
92         }
93
94         private boolean createWindow (int width, int height, boolean fullscreen) {
95                 if (fullscreen && fullscreenMonitor == 0) fullscreenMonitor = getWindowMonitor();
96
97                 glfwWindowHint(GLFW_VISIBLE, 0);
98                 glfwWindowHint(GLFW_RESIZABLE, resizable ? 1 : 0);
99                 glfwWindowHint(GLFW_UNDECORATED, undecorated ? 1 : 0);
100                 glfwWindowHint(GLFW_RED_BITS, bufferFormat.r);
101                 glfwWindowHint(GLFW_GREEN_BITS, bufferFormat.g);
102                 glfwWindowHint(GLFW_BLUE_BITS, bufferFormat.b);
103                 glfwWindowHint(GLFW_ALPHA_BITS, bufferFormat.a);
104                 glfwWindowHint(GLFW_DEPTH_BITS, bufferFormat.depth);
105                 glfwWindowHint(GLFW_STENCIL_BITS, bufferFormat.stencil);
106                 glfwWindowHint(GLFW_SAMPLES, bufferFormat.samples);
107
108                 boolean mouseCaptured = window != 0 && glfwGetInputMode(window, GLFW_CURSOR_MODE) == GLFW_CURSOR_CAPTURED;
109
110                 long oldWindow = window;
111                 long newWindow = glfwCreateWindow(width, height, title, fullscreen ? fullscreenMonitor : 0, oldWindow);
112                 if (newWindow == 0) return false;
113                 if (oldWindow != 0) glfwDestroyWindow(oldWindow);
114                 window = newWindow;
115                 this.width = Math.max(1, width);
116                 this.height = Math.max(1, height);
117
118                 this.fullscreen = fullscreen;
119                 if (!fullscreen) {
120                         if (x == -1 || y == -1) {
121                                 DisplayMode mode = getDesktopDisplayMode();
122                                 x = (mode.width - width) / 2;
123                                 y = (mode.height - height) / 2;
124                         }
125                         glfwSetWindowPos(window, x, y);
126                 }
127
128                 if (!mouseCaptured) glfwSetInputMode(window, GLFW_CURSOR_MODE, GLFW_CURSOR_NORMAL); // Prevent fullscreen from taking mouse.
129
130                 glfwMakeContextCurrent(newWindow);
131                 setVSync(vSync);
132                 if (visible) glfwShowWindow(window);
133
134                 return true;
135         }
136
137         void frameStart () {
138                 long time = System.nanoTime();
139                 if (lastTime == -1) lastTime = time;
140                 deltaTime = (time - lastTime) / 1000000000.0f;
141                 lastTime = time;
142
143                 if (time - frameStart >= 1000000000) {
144                         fps = frames;
145                         frames = 0;
146                         frameStart = time;
147                 }
148                 frames++;
149         }
150
151         void sizeChanged (int width, int height) {
152                 width = Math.max(1, width);
153                 height = Math.max(1, height);
154                 this.width = width;
155                 this.height = height;
156                 Gdx.gl.glViewport(0, 0, width, height);
157                 ApplicationListener listener = Gdx.app.getApplicationListener();
158                 if (listener != null) listener.resize(width, height);
159                 requestRendering();
160         }
161
162         void positionChanged (int x, int y) {
163                 this.x = x;
164                 this.y = y;
165         }
166
167         public boolean isGL11Available () {
168                 return gl11 != null;
169         }
170
171         public boolean isGL20Available () {
172                 return gl20 != null;
173         }
174
175         public GLCommon getGLCommon () {
176                 return gl;
177         }
178
179         public GL10 getGL10 () {
180                 return gl10;
181         }
182
183         public GL11 getGL11 () {
184                 return gl11;
185         }
186
187         public GL20 getGL20 () {
188                 return gl20;
189         }
190
191         public int getWidth () {
192                 return width;
193         }
194
195         public int getHeight () {
196                 return height;
197         }
198
199         public float getDeltaTime () {
200                 return deltaTime;
201         }
202
203         public float getRawDeltaTime () {
204                 return deltaTime;
205         }
206
207         public int getFramesPerSecond () {
208                 return fps;
209         }
210
211         public GraphicsType getType () {
212                 return GraphicsType.JGLFW;
213         }
214
215         public float getPpiX () {
216                 // return getWidth() / (glfwGetMonitorPhysicalWidth(getWindowMonitor()) * 0.03937f); // mm to inches
217                 return Toolkit.getDefaultToolkit().getScreenResolution();
218         }
219
220         public float getPpiY () {
221                 // return getHeight() / (glfwGetMonitorPhysicalHeight(getWindowMonitor()) * 0.03937f); // mm to inches
222                 return Toolkit.getDefaultToolkit().getScreenResolution();
223         }
224
225         public float getPpcX () {
226                 // return getWidth() / (glfwGetMonitorPhysicalWidth(getWindowMonitor()) / 10); // mm to cm
227                 return Toolkit.getDefaultToolkit().getScreenResolution() / 2.54f;
228         }
229
230         public float getPpcY () {
231                 // return getHeight() / (glfwGetMonitorPhysicalHeight(getWindowMonitor()) / 10); // mm to cm
232                 return Toolkit.getDefaultToolkit().getScreenResolution() / 2.54f;
233         }
234
235         public float getDensity () {
236                 // long monitor = getWindowMonitor();
237                 // float mmWidth = glfwGetMonitorPhysicalWidth(monitor);
238                 // float mmHeight = glfwGetMonitorPhysicalHeight(monitor);
239                 // float inches = (float)Math.sqrt(mmWidth * mmWidth + mmHeight * mmHeight) * 0.03937f; // mm to inches
240                 // float pixelWidth = getWidth();
241                 // float pixelHeight = getHeight();
242                 // float pixels = (float)Math.sqrt(pixelWidth * pixelWidth + pixelHeight * pixelHeight);
243                 // float diagonalPpi = pixels / inches;
244                 // return diagonalPpi / 160f;
245                 return Toolkit.getDefaultToolkit().getScreenResolution() / 160f;
246         }
247
248         public boolean supportsDisplayModeChange () {
249                 return true;
250         }
251
252         private long getWindowMonitor () {
253                 if (window != 0) {
254                         long monitor = glfwGetWindowMonitor(window);
255                         if (monitor != 0) return monitor;
256                 }
257                 return glfwGetPrimaryMonitor();
258         }
259
260         public DisplayMode[] getDisplayModes () {
261                 Array<DisplayMode> modes = new Array();
262                 for (GlfwVideoMode mode : glfwGetVideoModes(getWindowMonitor()))
263                         modes.add(new JglfwDisplayMode(mode.width, mode.height, 0, mode.redBits + mode.greenBits + mode.blueBits));
264                 return modes.toArray(DisplayMode.class);
265         }
266
267         public DisplayMode getDesktopDisplayMode () {
268                 GlfwVideoMode mode = glfwGetVideoMode(getWindowMonitor());
269                 return new JglfwDisplayMode(mode.width, mode.height, 0, mode.redBits + mode.greenBits + mode.blueBits);
270         }
271
272         public boolean setDisplayMode (DisplayMode displayMode) {
273                 bufferFormat = new BufferFormat( //
274                         displayMode.bitsPerPixel == 16 ? 5 : 8, //
275                         displayMode.bitsPerPixel == 16 ? 6 : 8, //
276                         displayMode.bitsPerPixel == 16 ? 6 : 8, //
277                         bufferFormat.a, bufferFormat.depth, bufferFormat.stencil, bufferFormat.samples, false);
278                 boolean success = createWindow(displayMode.width, displayMode.height, fullscreen);
279                 if (success && fullscreen) sizeChanged(displayMode.width, displayMode.height);
280                 return success;
281         }
282
283         public boolean setDisplayMode (int width, int height, boolean fullscreen) {
284                 if (fullscreen || this.fullscreen) {
285                         boolean success = createWindow(width, height, fullscreen);
286                         if (success && fullscreen) sizeChanged(width, height);
287                         return success;
288                 }
289
290                 glfwSetWindowSize(window, width, height);
291                 return true;
292         }
293
294         public void setTitle (String title) {
295                 if (title == null) title = "";
296                 glfwSetWindowTitle(window, title);
297                 this.title = title;
298         }
299
300         public void setVSync (boolean vsync) {
301                 this.vSync = vsync;
302                 glfwSwapInterval(vsync ? 1 : 0);
303         }
304
305         public BufferFormat getBufferFormat () {
306                 return bufferFormat;
307         }
308
309         public boolean supportsExtension (String extension) {
310                 return glfwExtensionSupported(extension);
311         }
312
313         public void setContinuousRendering (boolean isContinuous) {
314                 this.isContinuous = isContinuous;
315         }
316
317         public boolean isContinuousRendering () {
318                 return isContinuous;
319         }
320
321         public void requestRendering () {
322                 renderRequested = true;
323         }
324
325         public boolean isFullscreen () {
326                 return fullscreen;
327         }
328
329         /** Returns the JGLFW window handle. Note this should not be stored externally as it may change if the window is recreated to
330          * enter/exit fullscreen. */
331         public long getWindow () {
332                 return window;
333         }
334
335         public int getX () {
336                 return x;
337         }
338
339         public int getY () {
340                 return y;
341         }
342
343         public void setPosition (int x, int y) {
344                 glfwSetWindowPos(window, x, y);
345         }
346
347         public void hide () {
348                 visible = false;
349                 glfwHideWindow(window);
350         }
351
352         public void show () {
353                 visible = true;
354                 glfwShowWindow(window);
355
356                 Gdx.gl.glClearColor(initialBackgroundColor.r, initialBackgroundColor.g, initialBackgroundColor.b, initialBackgroundColor.a);
357                 Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
358                 glfwSwapBuffers(window);
359         }
360
361         public boolean isMinimized () {
362                 return glfwGetWindowParam(window, GLFW_ICONIFIED) == 1;
363         }
364
365         public void minimize () {
366                 glfwIconifyWindow(window);
367         }
368
369         public void restore () {
370                 glfwRestoreWindow(window);
371         }
372
373         boolean shouldRender () {
374                 try {
375                         return renderRequested || isContinuous;
376                 } finally {
377                         renderRequested = false;
378                 }
379         }
380
381         static class JglfwDisplayMode extends DisplayMode {
382                 protected JglfwDisplayMode (int width, int height, int refreshRate, int bitsPerPixel) {
383                         super(width, height, refreshRate, bitsPerPixel);
384                 }
385         }
386 }