2 package com.badlogic.gdx.backends.jglfw;
4 import static com.badlogic.jglfw.Glfw.*;
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;
16 import java.awt.GraphicsDevice;
17 import java.awt.GraphicsEnvironment;
18 import java.awt.Toolkit;
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;
25 JglfwApplicationConfiguration config;
28 int fullscreenMonitorIndex;
29 final BufferFormat bufferFormat;
30 volatile boolean isContinuous = true;
33 long frameStart, lastTime;
42 volatile boolean requestRendering;
44 public JglfwGraphics (JglfwApplicationConfiguration config) {
47 bufferFormat = new BufferFormat(config.r, config.g, config.b, config.a, config.depth, config.stencil, config.samples, false);
49 long fullscreenMonitor = glfwGetPrimaryMonitor();
50 long[] monitors = glfwGetMonitors();
51 // Find index of primary monitor.
52 for (int i = 0, n = monitors.length; i < n; i++) {
53 if (monitors[i] == fullscreenMonitor) {
54 fullscreenMonitorIndex = i;
58 // Find monitor specified in config.
59 if (config.fullscreen) {
60 if (monitors.length > 0) {
61 if (config.fullscreenMonitorIndex < monitors.length) fullscreenMonitorIndex = config.fullscreenMonitorIndex;
62 fullscreenMonitor = monitors[fullscreenMonitorIndex];
67 if (!createWindow(config.width, config.height, config.fullscreen)) {
68 throw new GdxRuntimeException("Unable to create window: " + config.width + "x" + config.height + ", fullscreen: "
71 if (config.x != -1 && config.y != -1) glfwSetWindowPos(window, config.x, config.y);
72 setVSync(config.vSync);
75 String version = GL.glGetString(GL11.GL_VERSION);
76 glMajorVersion = Integer.parseInt("" + version.charAt(0));
77 glMinorVersion = Integer.parseInt("" + version.charAt(2));
78 if (config.useGL20 && (glMajorVersion >= 2 || version.contains("2.1"))) { // special case for MESA, wtf...
79 // FIXME - Add check for whether GL 2.0 is actually supported.
80 gl20 = new JglfwGL20();
84 if (glMajorVersion == 1 && glMinorVersion < 5) {
85 gl10 = new JglfwGL10();
87 gl11 = new JglfwGL11();
98 public boolean isGL11Available () {
102 public boolean isGL20Available () {
106 public GLCommon getGLCommon () {
110 public GL10 getGL10 () {
114 public GL11 getGL11 () {
118 public GL20 getGL20 () {
122 public int getWidth () {
123 return glfwGetWindowWidth(window);
126 public int getHeight () {
127 return glfwGetWindowHeight(window);
131 long time = System.nanoTime();
132 deltaTime = (time - lastTime) / 1000000000.0f;
135 if (time - frameStart >= 1000000000) {
143 public float getDeltaTime () {
147 public float getRawDeltaTime () {
151 public int getFramesPerSecond () {
155 public GraphicsType getType () {
156 return GraphicsType.JGLFW;
159 public float getPpiX () {
160 return Toolkit.getDefaultToolkit().getScreenResolution();
163 public float getPpiY () {
164 return Toolkit.getDefaultToolkit().getScreenResolution();
167 public float getPpcX () {
168 return Toolkit.getDefaultToolkit().getScreenResolution() / 2.54f;
171 public float getPpcY () {
172 return Toolkit.getDefaultToolkit().getScreenResolution() / 2.54f;
175 public float getDensity () {
176 return Toolkit.getDefaultToolkit().getScreenResolution() / 160f;
179 public boolean supportsDisplayModeChange () {
183 public DisplayMode[] getDisplayModes () {
184 GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
185 java.awt.DisplayMode desktopMode = device.getDisplayMode();
186 java.awt.DisplayMode[] displayModes = device.getDisplayModes();
187 Array<DisplayMode> modes = new Array();
189 for (java.awt.DisplayMode mode : displayModes) {
190 for (DisplayMode other : modes)
191 if (other.width == mode.getWidth() && other.height == mode.getHeight() && other.bitsPerPixel == mode.getBitDepth())
192 continue outer; // Duplicate.
193 if (mode.getBitDepth() != desktopMode.getBitDepth()) continue;
194 modes.add(new JglfwDisplayMode(mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getBitDepth()));
196 return modes.toArray(DisplayMode.class);
199 public DisplayMode getDesktopDisplayMode () {
200 java.awt.DisplayMode mode = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode();
201 return new JglfwDisplayMode(mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getBitDepth());
204 public boolean setDisplayMode (DisplayMode displayMode) {
205 if (displayMode.bitsPerPixel != 0) glfwWindowHint(GLFW_DEPTH_BITS, displayMode.bitsPerPixel);
206 if (displayMode.bitsPerPixel != 0 || config.fullscreen)
207 return createWindow(displayMode.width, displayMode.height, config.fullscreen);
209 glfwSetWindowSize(window, displayMode.width, displayMode.height);
213 public boolean setDisplayMode (int width, int height, boolean fullscreen) {
214 if (window == 0 || fullscreen != config.fullscreen || config.fullscreen) return createWindow(width, height, fullscreen);
216 glfwSetWindowSize(window, width, height);
220 private boolean createWindow (int width, int height, boolean fullscreen) {
221 long fullscreenMonitor = 0;
223 long[] monitors = glfwGetMonitors();
224 if (monitors.length > 0)
225 fullscreenMonitor = fullscreenMonitorIndex < monitors.length ? monitors[fullscreenMonitorIndex] : 0;
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);
238 long oldWindow = window;
239 long newWindow = glfwCreateWindow(width, height, config.title, fullscreenMonitor, oldWindow);
240 if (newWindow == 0) return false;
241 if (oldWindow != 0) glfwDestroyWindow(oldWindow);
242 glfwMakeContextCurrent(newWindow);
244 config.fullscreen = fullscreen;
248 public void setTitle (String title) {
249 glfwSetWindowTitle(window, title);
250 config.title = title;
253 public void setVSync (boolean vsync) {
255 glfwSwapInterval(vsync ? 1 : 0);
258 public BufferFormat getBufferFormat () {
262 public boolean supportsExtension (String extension) {
263 return glfwExtensionSupported(extension);
266 public void setContinuousRendering (boolean isContinuous) {
267 this.isContinuous = isContinuous;
270 public boolean isContinuousRendering () {
274 public void requestRendering () {
275 synchronized (this) {
276 requestRendering = true;
280 public boolean isFullscreen () {
281 return config.fullscreen;
284 /** Returns the JGLFW window handle. Note this should not be stored externally as it may change if the window is recreated to
285 * enter/exit fullscreen. */
286 public long getWindow () {
290 boolean shouldRender () {
291 synchronized (this) {
292 boolean requestRendering = this.requestRendering;
293 this.requestRendering = false;
294 return requestRendering || isContinuous;
298 static class JglfwDisplayMode extends DisplayMode {
299 protected JglfwDisplayMode (int width, int height, int refreshRate, int bitsPerPixel) {
300 super(width, height, refreshRate, bitsPerPixel);