diff --git a/src/java/org/lwjgl/Display.java b/src/java/org/lwjgl/Display.java index b89d40cd..05a400fa 100644 --- a/src/java/org/lwjgl/Display.java +++ b/src/java/org/lwjgl/Display.java @@ -34,6 +34,7 @@ package org.lwjgl; import java.util.HashSet; import java.util.Arrays; + /** * $Id$ * @@ -49,6 +50,7 @@ public final class Display { static { System.loadLibrary(Sys.getLibraryName()); + init(); } /** Has the display been created? */ @@ -83,6 +85,12 @@ public final class Display { private Display() { super(); } + + /** + * Initialize. This determines, natively, the current display mode and stashes + * it back in the mode static member. + */ + private static native void init(); /** * Returns the entire list of display modes as an array, in no @@ -116,89 +124,29 @@ public final class Display { /** * Native method for getting displaymodes */ - public static native DisplayMode[] nGetAvailableDisplayModes(); - + private static native DisplayMode[] nGetAvailableDisplayModes(); + /** - * Create a display with the specified display mode. If the display is - * already created then no action is taken - the display must first be - * destroyed. - * - * @param displayMode A display mode to choose - * @param alpha Minimun number of alpha bits on the display - * @param depth Minimun number of depth bits on the display - * @param stencil Minimun number of stencil bits on the display - * @param fullscreen Whether to create the display fullscreen - * @param title The title for the application + * Set the current display mode. The underlying OS may not use an exact match for + * the specified display mode. After successfully calling setDisplayMode() you will + * still need to query the display's characteristics using getDisplayMode(). + * @param newMode The new display mode to set * @throws Exception if the display mode could not be set - * @see #destroy() */ - public static void create(DisplayMode displayMode, int alpha, int depth, int stencil, boolean fullscreen, String title) - throws Exception { - - if (created) { - return; - } - - if (!nCreate(displayMode.width, - displayMode.height, - displayMode.bpp, - displayMode.freq, - alpha, - depth, - stencil, - fullscreen, - title)) { - throw new Exception("Failed to set display mode to " + displayMode); - } - - created = true; - mode = displayMode; - } - + public static native void setDisplayMode(DisplayMode mode) throws Exception; + /** - * Native method to create the display. This will set the handle if it is - * successful. - * @return true if the display was successfully created - * @see #create(org.lwjgl.DisplayMode, boolean) + * Reset the display mode to whatever it was when LWJGL was initialized. + * Fails silently. */ - private static native boolean nCreate( - int width, - int height, - int bpp, - int freq, - int alpha_bits, - int depth_bits, - int stencil_bits, - boolean fullscreen, - String title); - - /** - * Destroy the display and return it to normal. If the display has not yet - * been created no action is taken. - */ - public static void destroy() { - if (!created) { - return; - } - - nDestroy(); - created = false; - mode = null; - } - - /** - * Native method to destroy the display. This will reset the handle. - */ - private static native void nDestroy(); + public static native void resetDisplayMode() throws Exception; /** * Retrieves the width of the created display * * @return the current display width. - * @throws AssertionError if the display has not been created yet. */ public static int getWidth() { - assert created : "The display has not been created yet."; return mode.width; } @@ -206,10 +154,8 @@ public final class Display { * Retrieves the height of the created display * * @return the current display height. - * @throws AssertionError if the display has not been created yet. */ public static int getHeight() { - assert created : "The display has not been created yet."; return mode.height; } @@ -217,10 +163,8 @@ public final class Display { * Retrieves the current display depth of the created display * * @return the current display depth. - * @throws AssertionError if the display has not been created yet. */ public static int getDepth() { - assert created : "The display has not been created yet."; return mode.bpp; } @@ -228,27 +172,14 @@ public final class Display { * Retrieves the current display frequency of the created display * * @return the current display frequency. - * @throws AssertionError if the display has not been created yet. */ public static int getFrequency() { - assert created : "The display has not been created yet."; return mode.freq; } /** - * Retrieves the DisplayMode that the display has currently been - * set to. - * - * @return the current display mode, or null if the display is not yet created - * @throws AssertionError if the display has not been created yet. - */ - public static DisplayMode getDisplayMode() { - assert created : "The display has not been created yet."; - return mode; - } - - /** - * Retrieves the native handle to the created window + * Retrieves the native handle to the created window. The meaning of this value + * is platform specific. Under Win32, it is an HWND. * * @return the native handle * @throws AssertionError if the display has not been created yet. @@ -258,37 +189,6 @@ public final class Display { return handle; } - /** - * Tests whether or not the display has been created - * - * @return true if the display has been created - */ - public static boolean isCreated() { - return created; - } - - /** - * Determines if the display is minimized. When the display is minimized it is - * effectively invisible, and you need perform no rendering in your game loop. - * On the native side, when the application is switched to some other application, - * the display window will minimize; when focus is regained, it will maximize and - * automatically gain focus and become the foreground window again. - * @return true if the display is minimized - */ - public static native boolean isMinimized(); - - /** - * Determines if the user has requested that the application should close. - * When a user has requested that the application should shutdown, it is up to - * the application to perform the actual shutdown and cleanup of any allocated - * resources. - * - * @return true if the user has requested that the application should close - */ - public static boolean isCloseRequested() { - return closeRequested; - } - /** * Returns the operating system windowing platform. This will be one of the * constants defined above. There is no "unknown" platform; a native library port @@ -299,5 +199,21 @@ public final class Display { */ public static native int getPlatform(); + /** + * Obtains the display's gamma ramp. The gamma ramp returned is an array of + * integers in the range 0..255. If gamma is not supported by the underlying + * hardware then null is returned. + * @return an array of ints, or null + */ + public static native int[] getGammaRamp(); + + /** + * Sets the display's gamma ramp. The gamma ramp should be an array of ints + * in the range 0...255. The length of the array should match the length of the + * array returned by getGammaRamp(). + * + * If the underlying hardware does not support gamma then this command is a no-op. + */ + public static native void setGammaRamp(int[] gamma); } diff --git a/src/java/org/lwjgl/Window.java b/src/java/org/lwjgl/Window.java new file mode 100644 index 00000000..c77c01c6 --- /dev/null +++ b/src/java/org/lwjgl/Window.java @@ -0,0 +1,175 @@ +/* + * Created on 27-Mar-2003 + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code Template + */ +package org.lwjgl; + +/** + * This is the abstract base class for a Window in LWJGL. LWJGL windows have some + * peculiar characteristics: + * + * - width and height are always fixed and cannot be changed + * - the position of the window may or may not be programmable but once specified + * cannot be changed + * - the window may be closeable by the user or operating system, and may be minimized + * by the user or operating system + * - the operating system may or may not allow more than one window to be constructed + * at any one time. There is no guarantee that all windows can be visible at once. + * - the operating system may or may not be able to do fullscreen or windowed windows. + * + * @author foo + */ +public abstract class Window { + + static { + System.loadLibrary(Sys.getLibraryName()); + } + + /** The window's native data structure. On Win32 this is an HWND. */ + private int handle; + + /** Whether the window is currently minimized */ + private boolean minimized; + + /** Whether the window has been asked to close by the user or underlying OS */ + private boolean closeRequested; + + /** Whether the window is dirty, ie. needs painting */ + private boolean dirty; + + /** X coordinate of the window */ + private int x; + + /** + * Y coordinate of the window. Y in window coordinates is from the top of the display down, + * unlike GL, where it is typically at the bottom of the display. + */ + private int y; + + /** Width of the window */ + private final int width; + + /** Height of the window */ + private final int height; + + /** Title of the window */ + private String title; + + /** + * Construct a Window. Some OSs may not support non-fullscreen windows; in + * which case the window will be fullscreen regardless. + * + * In this abstract base class, no actual window peer is constructed. This should be + * done in specialised derived classes. + * + * @param title The window's title + * @param x, y, width, height The position and dimensions of the client area of + * the window. The dimensions may be ignored if the window cannot be made non- + * fullscreen. The position may be ignored in either case. + */ + protected Window(String title, int x, int y, int width, int height) { + this.title = title; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + /** + * @return the width of the window + */ + public final int getWidth() { + return width; + } + + /** + * @return the height of the window + */ + public final int getHeight() { + return height; + } + + /** + * @return the title of the window + */ + public final String getTitle() { + return title; + } + + /** + * Set the title of the window. This may be ignored by the underlying OS. + * @param newTitle The new window title + */ + public final void setTitle(String newTitle) { + title = newTitle; + nSetTitle(); + } + + /** + * Native implementation of setTitle(). This will read the window's title member + * and stash it in the native title of the window. + */ + private native void nSetTitle(); + + /** + * @return true if the user or operating system has asked the window to close + */ + public final boolean isCloseRequested() { + return closeRequested; + } + + /** + * @return true if the window is minimized or otherwise not visible + */ + public final boolean isMinimized() { + return minimized; + } + + /** + * Determine if the window's contents have been damaged by external events. + * If you are writing a straightforward game rendering loop and simply paint + * every frame regardless, you can ignore this flag altogether. If you are + * trying to be kind to other processes you can check this flag and only + * redraw when it returns true. The flag is cleared when you call paint(). + * + * @return true if the window has been damaged by external changes + * and needs to repaint itself + */ + public final boolean isDirty() { + return dirty; + } + + /** + * Paint the window. This clears the dirty flag and swaps the buffers. + */ + public final void paint() { + dirty = false; + swapBuffers(); + } + + /** + * Swap the buffers. + */ + private native void swapBuffers(); + + /** + * Destroy the window. + */ + public final native void destroy(); + + /** + * @return the native window handle + */ + public final int getHandle() { + return handle; + } + + /** + * 'Tick' the window. This must be called at least once per video frame + * to handle window close requests, moves, paints, etc. + */ + public final native void tick(); + +} diff --git a/src/java/org/lwjgl/opengl/BaseGL.java b/src/java/org/lwjgl/opengl/BaseGL.java index f8cca86e..87417bc1 100644 --- a/src/java/org/lwjgl/opengl/BaseGL.java +++ b/src/java/org/lwjgl/opengl/BaseGL.java @@ -190,4 +190,166 @@ abstract class BaseGL { && Thread.currentThread() == renderThread; } + /** + * Create a fullscreen display. If the display has already been created then this + * method is a no-op. + * + * Alpha, depth, and stencil will be 0 bits. + * + * @param title The title for the application + * @throws Exception if the window could not be created for any reason + * @see #destroy() + */ + public static void create(String title) throws Exception { + create(title, 0, 0, 0); + } + + /** + * Create a fullscreen display. If the display has already been created then this + * method is a no-op. + * + * @param title The title for the application + * @param alpha Minimun number of alpha bits on the display + * @param depth Minimun number of depth bits on the display + * @param stencil Minimun number of stencil bits on the display + * @throws Exception if the window could not be created for any reason + * @see #destroy() + */ + public static void create(String title, int alpha, int depth, int stencil) + throws Exception { + + if (Display.created) { + return; + } + + if (!nCreateFullscreen(title, alpha, depth, stencil)) { + throw new Exception("Failed to create fullscreen display."); + } + + Display.created = true; + } + + /** + * Create a windowed display. If the display has already been created then this + * method is a no-op. + * + * The window is not guaranteed to be positioned at (x, y). Nor is it guaranteed + * to have a drag bar, title bar, close button, or minimized button. It cannot be + * resized once created. + * + * The window will have 0 bits alpha, depth, and stencil. + * + * @param title The title for the application + * @param x, y The position of the window + * @param width, height The dimensions of the drawable area of the window + * @throws Exception if the window could not be created for any reason + * @see #destroy() + */ + public static void create(String title, int x, int y, int width, int height) + throws Exception { + + create(title, x, y, width, height, 0, 0, 0); + + } + + /** + * Create a windowed display. If the display has already been created then this + * method is a no-op. + * + * The window is not guaranteed to be positioned at (x, y). Nor is it guaranteed + * to have a drag bar, title bar, close button, or minimized button. It cannot be + * resized once created. + * + * @param title The title for the application + * @param x, y The position of the window + * @param width, height The dimensions of the drawable area of the window + * @param alpha Minimun number of alpha bits on the display + * @param depth Minimun number of depth bits on the display + * @param stencil Minimun number of stencil bits on the display + * @throws Exception if the window could not be created for any reason + * @see #destroy() + */ + public static void create(String title, int x, int y, int width, int height, int alpha, int depth, int stencil) + throws Exception { + + if (Display.created) { + return; + } + + if (!nCreateWindowed(title, x, y, width, height, alpha, depth, stencil)) { + throw new Exception("Failed to create windowed display."); + } + + Display.created = true; + } + + /** + * Native method to create the display. This will set the handle if it is + * successful. + * @return true if the display was successfully created + * @see #create(org.lwjgl.DisplayMode, boolean) + */ + private static native boolean nCreateWindowed( + String title, + int x, + int y, + int width, + int height, + int alpha_bits, + int depth_bits, + int stencil_bits); + + /** + * Native method to create the display. This will set the handle if it is + * successful. + * @return true if the display was successfully created + * @see #create(org.lwjgl.DisplayMode, boolean) + */ + private static native boolean nCreateFullscreen( + String title, + int alpha_bits, + int depth_bits, + int stencil_bits); + + /** + * Destroy the display and return it to normal. If the display has not yet + * been created no action is taken. + */ + public static void destroy() { + if (!Display.created) { + return; + } + + nDestroy(); + Display.created = false; + Display.mode = null; + } + + /** + * Native method to destroy the display. This will reset the handle. + */ + private static native void nDestroy(); + + /** + * Determines if the display is minimized. When the display is minimized it is + * effectively invisible, and you need perform no rendering in your game loop. + * On the native side, when the application is switched to some other application, + * the display window will minimize; when focus is regained, it will maximize and + * automatically gain focus and become the foreground window again. + * @return true if the display is minimized + */ + public static native boolean isMinimized(); + + /** + * Determines if the user has requested that the application should close. + * When a user has requested that the application should shutdown, it is up to + * the application to perform the actual shutdown and cleanup of any allocated + * resources. + * + * @return true if the user has requested that the application should close + */ + public static boolean isCloseRequested() { + return Display.closeRequested; + } + } diff --git a/src/java/org/lwjgl/test/WindowCreationTest.java b/src/java/org/lwjgl/test/WindowCreationTest.java index 8d6c9e3b..25a32bef 100644 --- a/src/java/org/lwjgl/test/WindowCreationTest.java +++ b/src/java/org/lwjgl/test/WindowCreationTest.java @@ -7,6 +7,7 @@ package org.lwjgl.test; import org.lwjgl.*; +import org.lwjgl.opengl.BaseGL; /** * @author Brian @@ -43,6 +44,6 @@ public class WindowCreationTest { System.out.println("Display created"); - Display.destroy(); + BaseGL.destroy(); } } \ No newline at end of file diff --git a/src/java/org/lwjgl/test/input/ControllerCreationTest.java b/src/java/org/lwjgl/test/input/ControllerCreationTest.java index 4af967d4..8eb4b440 100644 --- a/src/java/org/lwjgl/test/input/ControllerCreationTest.java +++ b/src/java/org/lwjgl/test/input/ControllerCreationTest.java @@ -35,6 +35,7 @@ import org.lwjgl.Sys; import org.lwjgl.Display; import org.lwjgl.DisplayMode; import org.lwjgl.input.Controller; +import org.lwjgl.opengl.*; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GLU; import org.lwjgl.vector.Vector2f; @@ -118,7 +119,7 @@ public class ControllerCreationTest { // recreate display in fullscreen mode System.out.print("Destroying display..."); - Display.destroy(); + BaseGL.destroy(); System.out.println("success"); System.out.print("Entering fullscreen mode..."); @@ -140,7 +141,7 @@ public class ControllerCreationTest { System.out.print("Shutting down..."); Controller.destroy(); gl.destroy(); - Display.destroy(); + BaseGL.destroy(); System.out.println("shutdown complete"); } diff --git a/src/java/org/lwjgl/test/input/MouseCreationTest.java b/src/java/org/lwjgl/test/input/MouseCreationTest.java index f4b839dc..5d8c5dbf 100644 --- a/src/java/org/lwjgl/test/input/MouseCreationTest.java +++ b/src/java/org/lwjgl/test/input/MouseCreationTest.java @@ -35,6 +35,7 @@ import org.lwjgl.Sys; import org.lwjgl.Display; import org.lwjgl.DisplayMode; import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.*; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GLU; import org.lwjgl.vector.Vector2f; @@ -118,7 +119,7 @@ public class MouseCreationTest { // recreate display in fullscreen mode System.out.print("Destroying display..."); - Display.destroy(); + BaseGL.destroy(); System.out.println("success"); System.out.print("Entering fullscreen mode..."); @@ -140,7 +141,7 @@ public class MouseCreationTest { System.out.print("Shutting down..."); Mouse.destroy(); gl.destroy(); - Display.destroy(); + BaseGL.destroy(); System.out.println("shutdown complete"); } diff --git a/src/java/org/lwjgl/test/input/MouseTest.java b/src/java/org/lwjgl/test/input/MouseTest.java index 89a8126c..a6827d8c 100644 --- a/src/java/org/lwjgl/test/input/MouseTest.java +++ b/src/java/org/lwjgl/test/input/MouseTest.java @@ -35,6 +35,7 @@ import org.lwjgl.Display; import org.lwjgl.DisplayMode; import org.lwjgl.input.Mouse; import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.*; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GLU; import org.lwjgl.vector.Vector2f; @@ -118,7 +119,7 @@ public class MouseTest { Mouse.destroy(); Keyboard.destroy(); gl.destroy(); - Display.destroy(); + BaseGL.destroy(); } private void createMouse() { @@ -131,8 +132,8 @@ public class MouseTest { } private void wiggleMouse() { - while (!Display.isCloseRequested()) { - if(Display.isMinimized()) { + while (!BaseGL.isCloseRequested()) { + if(BaseGL.isMinimized()) { continue; } diff --git a/src/java/org/lwjgl/test/opengl/Game.java b/src/java/org/lwjgl/test/opengl/Game.java index b97ca899..e5209d78 100644 --- a/src/java/org/lwjgl/test/opengl/Game.java +++ b/src/java/org/lwjgl/test/opengl/Game.java @@ -45,7 +45,7 @@ import org.lwjgl.*; import org.lwjgl.opengl.*; import org.lwjgl.input.*; -import java.nio.*; +import java.nio.*; public final class Game { static { @@ -188,6 +188,6 @@ public final class Game { Keyboard.destroy(); Mouse.destroy(); gl.destroy(); - Display.destroy(); + BaseGL.destroy(); } } diff --git a/src/java/org/lwjgl/test/opengl/Grass.java b/src/java/org/lwjgl/test/opengl/Grass.java index d1a21fea..15ea3656 100644 --- a/src/java/org/lwjgl/test/opengl/Grass.java +++ b/src/java/org/lwjgl/test/opengl/Grass.java @@ -214,7 +214,7 @@ public class Grass { Mouse.destroy(); Keyboard.destroy(); gl.destroy(); - Display.destroy(); + BaseGL.destroy(); } private static float myrand() {