OSDN Git Service

GLFW backend works! Yay!
[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.Gdx;
7 import com.badlogic.gdx.Graphics;
8 import com.badlogic.gdx.graphics.GL10;
9 import com.badlogic.gdx.graphics.GL11;
10 import com.badlogic.gdx.graphics.GL20;
11 import com.badlogic.gdx.graphics.GLCommon;
12 import com.badlogic.gdx.utils.Array;
13 import com.badlogic.gdx.utils.GdxRuntimeException;
14 import com.badlogic.jglfw.gl.GL;
15
16 import java.awt.GraphicsDevice;
17 import java.awt.GraphicsEnvironment;
18 import java.awt.Toolkit;
19
20 /** An implementation of the {@link Graphics} interface based on GLFW.
21  * @author Nathan Sweet */
22 public class JglfwGraphics implements Graphics {
23         static int glMajorVersion, glMinorVersion;
24
25         JglfwApplicationConfiguration config;
26         long window;
27         boolean fullscreen;
28         int fullscreenMonitorIndex;
29         final BufferFormat bufferFormat;
30         volatile boolean isContinuous = true;
31
32         float deltaTime;
33         long frameStart, lastTime;
34         int frames, fps;
35
36         GLCommon gl;
37         JglfwGL10 gl10;
38         JglfwGL11 gl11;
39         JglfwGL20 gl20;
40
41         boolean sync;
42         boolean resize;
43         volatile boolean requestRendering;
44
45         public JglfwGraphics (JglfwApplicationConfiguration config) {
46                 this.config = config;
47
48                 bufferFormat = new BufferFormat(config.r, config.g, config.b, config.a, config.depth, config.stencil, config.samples, false);
49
50                 createWindow();
51                 createGL();
52         }
53
54         private void createWindow () {
55                 long fullscreenMonitor = glfwGetPrimaryMonitor();
56                 long[] monitors = glfwGetMonitors();
57                 // Find index of primary monitor.
58                 for (int i = 0, n = monitors.length; i < n; i++) {
59                         if (monitors[i] == fullscreenMonitor) {
60                                 fullscreenMonitorIndex = i;
61                                 break;
62                         }
63                 }
64                 // Find monitor specified in config.
65                 if (config.fullscreen) {
66                         if (monitors.length > 0) {
67                                 if (config.fullscreenMonitorIndex < monitors.length) fullscreenMonitorIndex = config.fullscreenMonitorIndex;
68                                 fullscreenMonitor = monitors[fullscreenMonitorIndex];
69                         }
70                 }
71
72                 // Create window.
73                 if (!setDisplayMode(config.width, config.height, config.fullscreen)) {
74                         throw new GdxRuntimeException("Unable to create window: " + config.width + "x" + config.height + ", fullscreen: "
75                                 + config.fullscreen);
76                 }
77
78                 setVSync(config.vSync);
79                 if (config.x != -1 && config.y != -1) glfwSetWindowPos(window, config.x, config.y);
80         }
81
82         private void createGL () {
83                 String version = GL.glGetString(GL11.GL_VERSION);
84                 glMajorVersion = Integer.parseInt("" + version.charAt(0));
85                 glMinorVersion = Integer.parseInt("" + version.charAt(2));
86
87                 if (config.useGL20 && (glMajorVersion >= 2 || version.contains("2.1"))) { // special case for MESA, wtf...
88                         // FIXME - Add check for whether GL 2.0 is actually supported.
89                         gl20 = new JglfwGL20();
90                         gl = gl20;
91                 } else {
92                         gl20 = null;
93                         if (glMajorVersion == 1 && glMinorVersion < 5) {
94                                 gl10 = new JglfwGL10();
95                         } else {
96                                 gl11 = new JglfwGL11();
97                                 gl10 = gl11;
98                         }
99                         gl = gl10;
100                 }
101
102                 Gdx.gl = gl;
103                 Gdx.gl10 = gl10;
104                 Gdx.gl11 = gl11;
105                 Gdx.gl20 = gl20;
106         }
107
108         public boolean isGL11Available () {
109                 return gl11 != null;
110         }
111
112         public boolean isGL20Available () {
113                 return gl20 != null;
114         }
115
116         public GLCommon getGLCommon () {
117                 return gl;
118         }
119
120         public GL10 getGL10 () {
121                 return gl10;
122         }
123
124         public GL11 getGL11 () {
125                 return gl11;
126         }
127
128         public GL20 getGL20 () {
129                 return gl20;
130         }
131
132         public int getWidth () {
133                 return glfwGetWindowWidth(window);
134         }
135
136         public int getHeight () {
137                 return glfwGetWindowHeight(window);
138         }
139
140         void updateTime () {
141                 long time = System.nanoTime();
142                 deltaTime = (time - lastTime) / 1000000000.0f;
143                 lastTime = time;
144
145                 if (time - frameStart >= 1000000000) {
146                         fps = frames;
147                         frames = 0;
148                         frameStart = time;
149                 }
150                 frames++;
151         }
152
153         public float getDeltaTime () {
154                 return deltaTime;
155         }
156
157         public float getRawDeltaTime () {
158                 return deltaTime;
159         }
160
161         public int getFramesPerSecond () {
162                 return fps;
163         }
164
165         public GraphicsType getType () {
166                 return GraphicsType.JGLFW;
167         }
168
169         public float getPpiX () {
170                 return Toolkit.getDefaultToolkit().getScreenResolution();
171         }
172
173         public float getPpiY () {
174                 return Toolkit.getDefaultToolkit().getScreenResolution();
175         }
176
177         public float getPpcX () {
178                 return Toolkit.getDefaultToolkit().getScreenResolution() / 2.54f;
179         }
180
181         public float getPpcY () {
182                 return Toolkit.getDefaultToolkit().getScreenResolution() / 2.54f;
183         }
184
185         public float getDensity () {
186                 return Toolkit.getDefaultToolkit().getScreenResolution() / 160f;
187         }
188
189         public boolean supportsDisplayModeChange () {
190                 return true;
191         }
192
193         public DisplayMode[] getDisplayModes () {
194                 GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
195                 java.awt.DisplayMode desktopMode = device.getDisplayMode();
196                 java.awt.DisplayMode[] displayModes = device.getDisplayModes();
197                 Array<DisplayMode> modes = new Array();
198                 outer:
199                 for (java.awt.DisplayMode mode : displayModes) {
200                         for (DisplayMode other : modes)
201                                 if (other.width == mode.getWidth() && other.height == mode.getHeight() && other.bitsPerPixel == mode.getBitDepth())
202                                         continue outer; // Duplicate.
203                         if (mode.getBitDepth() != desktopMode.getBitDepth()) continue;
204                         modes.add(new JglfwDisplayMode(mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getBitDepth()));
205                 }
206                 return modes.toArray(DisplayMode.class);
207         }
208
209         public DisplayMode getDesktopDisplayMode () {
210                 java.awt.DisplayMode mode = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode();
211                 return new JglfwDisplayMode(mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getBitDepth());
212         }
213
214         public boolean setDisplayMode (DisplayMode displayMode) {
215                 if (displayMode.bitsPerPixel != 0) glfwWindowHint(GLFW_DEPTH_BITS, displayMode.bitsPerPixel);
216                 glfwSetWindowSize(window, displayMode.width, displayMode.height);
217                 return true;
218         }
219
220         public boolean setDisplayMode (int width, int height, boolean fullscreen) {
221                 if (window == 0 || fullscreen != config.fullscreen) {
222                         long fullscreenMonitor = 0;
223                         long[] monitors = glfwGetMonitors();
224                         if (monitors.length > 0)
225                                 fullscreenMonitor = fullscreenMonitorIndex < monitors.length ? monitors[fullscreenMonitorIndex] : 0;
226
227                         // need to set the window hints every time we create a window, glfwCreateWindow resets them.
228                         glfwWindowHint(GLFW_RESIZABLE, config.resizable ? 1 : 0);
229                         glfwWindowHint(GLFW_RED_BITS, config.r);
230                         glfwWindowHint(GLFW_GREEN_BITS, config.g);
231                         glfwWindowHint(GLFW_BLUE_BITS, config.b);
232                         glfwWindowHint(GLFW_ALPHA_BITS, config.a);
233                         glfwWindowHint(GLFW_DEPTH_BITS, config.depth);
234                         glfwWindowHint(GLFW_STENCIL_BITS, config.stencil);
235                         glfwWindowHint(GLFW_SAMPLES, config.samples);
236                         glfwWindowHint(GLFW_DEPTH_BITS, config.bitsPerPixel);
237
238                         // share old window if any, so context service
239                         long window = glfwCreateWindow(config.width, config.height, config.title, 0, this.window);
240                         if (window == 0) return false;
241                         if (this.window != 0) glfwDestroyWindow(window);
242                         glfwMakeContextCurrent(window);
243                         this.window = window;
244                         return true;
245                 }
246                 glfwSetWindowSize(window, width, height);
247                 return true;
248         }
249
250         public void setTitle (String title) {
251                 glfwSetWindowTitle(window, title);
252         }
253
254         public void setVSync (boolean vsync) {
255                 this.sync = vsync;
256                 glfwSwapInterval(vsync ? 1 : 0);
257         }
258
259         public BufferFormat getBufferFormat () {
260                 return bufferFormat;
261         }
262
263         public boolean supportsExtension (String extension) {
264                 return glfwExtensionSupported(extension);
265         }
266
267         public void setContinuousRendering (boolean isContinuous) {
268                 this.isContinuous = isContinuous;
269         }
270
271         public boolean isContinuousRendering () {
272                 return isContinuous;
273         }
274
275         public void requestRendering () {
276                 synchronized (this) {
277                         requestRendering = true;
278                 }
279         }
280
281         public boolean isFullscreen () {
282                 return config.fullscreen;
283         }
284
285         /** Returns the JGLFW window handle. Note this should not be stored externally as it may change if the window is recreated to
286          * enter/exit fullscreen. */
287         public long getWindow () {
288                 return window;
289         }
290
291         boolean shouldRender () {
292                 synchronized (this) {
293                         boolean requestRendering = this.requestRendering;
294                         this.requestRendering = false;
295                         return requestRendering || isContinuous;
296                 }
297         }
298
299         static class JglfwDisplayMode extends DisplayMode {
300                 protected JglfwDisplayMode (int width, int height, int refreshRate, int bitsPerPixel) {
301                         super(width, height, refreshRate, bitsPerPixel);
302                 }
303         }
304 }