2004-04-03 16:05:57 -05:00
|
|
|
/*
|
2004-06-12 16:28:34 -04:00
|
|
|
* Copyright (c) 2002-2004 LWJGL Project
|
2004-02-04 17:06:18 -05:00
|
|
|
* All rights reserved.
|
2004-04-03 16:05:57 -05:00
|
|
|
*
|
2004-02-04 17:06:18 -05:00
|
|
|
* Redistribution and use in source and binary forms, with or without
|
2004-04-03 16:05:57 -05:00
|
|
|
* modification, are permitted provided that the following conditions are
|
2004-02-04 17:06:18 -05:00
|
|
|
* met:
|
2004-04-03 16:05:57 -05:00
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
2004-02-04 17:06:18 -05:00
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2003-03-27 17:32:48 -05:00
|
|
|
*
|
2004-06-12 16:28:34 -04:00
|
|
|
* * Neither the name of 'LWJGL' nor the names of
|
2004-04-03 16:05:57 -05:00
|
|
|
* its contributors may be used to endorse or promote products derived
|
2004-02-04 17:06:18 -05:00
|
|
|
* from this software without specific prior written permission.
|
2004-04-03 16:05:57 -05:00
|
|
|
*
|
2004-02-04 17:06:18 -05:00
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
2004-04-03 16:05:57 -05:00
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
2004-02-04 17:06:18 -05:00
|
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
2004-04-03 16:05:57 -05:00
|
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
2004-02-04 17:06:18 -05:00
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2003-03-27 17:32:48 -05:00
|
|
|
*/
|
2003-08-04 06:09:40 -04:00
|
|
|
package org.lwjgl.opengl;
|
2003-03-27 17:32:48 -05:00
|
|
|
|
|
|
|
/**
|
2003-08-03 18:05:40 -04:00
|
|
|
* This is the abstract class for a Window in LWJGL. LWJGL windows have some
|
2003-03-27 17:32:48 -05:00
|
|
|
* peculiar characteristics:
|
2004-04-03 16:05:57 -05:00
|
|
|
*
|
2003-03-27 17:32:48 -05:00
|
|
|
* - the window may be closeable by the user or operating system, and may be minimized
|
|
|
|
* by the user or operating system
|
2003-03-27 17:46:25 -05:00
|
|
|
* - only one window may ever be open at once
|
2003-03-27 17:32:48 -05:00
|
|
|
* - the operating system may or may not be able to do fullscreen or windowed windows.
|
2004-04-03 16:05:57 -05:00
|
|
|
*
|
2003-03-27 17:32:48 -05:00
|
|
|
* @author foo
|
|
|
|
*/
|
2003-08-04 06:09:40 -04:00
|
|
|
|
|
|
|
import org.lwjgl.Sys;
|
2004-03-26 06:01:34 -05:00
|
|
|
import org.lwjgl.input.Controller;
|
|
|
|
import org.lwjgl.input.Keyboard;
|
2004-03-21 16:54:57 -05:00
|
|
|
import org.lwjgl.input.Mouse;
|
2004-03-27 10:05:24 -05:00
|
|
|
import org.lwjgl.LWJGLException;
|
2004-07-02 15:02:00 -04:00
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
import java.nio.ByteOrder;
|
|
|
|
import java.nio.FloatBuffer;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.HashSet;
|
2003-08-04 06:09:40 -04:00
|
|
|
|
2004-07-02 15:02:00 -04:00
|
|
|
public final class Display {
|
2003-03-27 17:32:48 -05:00
|
|
|
|
2004-07-03 09:13:54 -04:00
|
|
|
/** The current display mode, if created */
|
|
|
|
private static DisplayMode current_mode;
|
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
static {
|
2004-03-27 08:48:58 -05:00
|
|
|
Sys.initialize();
|
2004-07-02 15:02:00 -04:00
|
|
|
current_mode = init();
|
2004-07-03 09:13:54 -04:00
|
|
|
assert current_mode != null;
|
|
|
|
System.out.println("Current mode "+current_mode);
|
2004-07-03 13:39:25 -04:00
|
|
|
Runtime.getRuntime().addShutdownHook(new Thread() {
|
|
|
|
public void run() {
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
});
|
2003-10-01 05:33:22 -04:00
|
|
|
}
|
2003-09-29 05:26:20 -04:00
|
|
|
|
2004-07-02 15:02:00 -04:00
|
|
|
/** Timer for sync() */
|
|
|
|
private static long timeNow, timeThen;
|
|
|
|
|
|
|
|
// /** X coordinate of the window */
|
|
|
|
// private static int x;
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2004-07-02 15:02:00 -04:00
|
|
|
// private static int y;
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/** Title of the window */
|
2003-08-02 13:11:33 -04:00
|
|
|
private static String title;
|
2003-08-03 18:05:40 -04:00
|
|
|
|
|
|
|
/** Fullscreen */
|
|
|
|
private static boolean fullscreen;
|
2004-07-03 13:39:25 -04:00
|
|
|
|
|
|
|
/** VSync */
|
|
|
|
private static boolean vsync;
|
2004-04-03 18:01:39 -05:00
|
|
|
|
2003-08-04 19:00:49 -04:00
|
|
|
/** Tracks VBO state for the window context */
|
|
|
|
private static VBOTracker vbo_tracker;
|
2004-04-03 16:05:57 -05:00
|
|
|
|
2003-11-03 06:23:56 -05:00
|
|
|
/** A unique context object, so we can track different contexts between creates() and destroys() */
|
2004-07-02 15:02:00 -04:00
|
|
|
private static Display context;
|
2004-04-03 16:05:57 -05:00
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
2003-11-03 06:23:56 -05:00
|
|
|
* Only constructed by ourselves
|
2003-03-27 17:32:48 -05:00
|
|
|
*/
|
2004-07-02 15:02:00 -04:00
|
|
|
private Display() {
|
2003-03-27 17:32:48 -05:00
|
|
|
}
|
|
|
|
|
2004-04-03 18:01:39 -05:00
|
|
|
/**
|
2004-07-02 15:02:00 -04:00
|
|
|
* Returns the entire list of display modes as an array, in no
|
|
|
|
* particular order. Any given mode is not guaranteed to be available and
|
|
|
|
* the only certain way to check is to call create() and make sure it works.
|
|
|
|
* Only non-palette-indexed modes are returned (ie. bpp will be 16, 24, or 32).
|
|
|
|
*
|
|
|
|
* @return an array of all display modes the system reckons it can handle.
|
2004-04-03 18:01:39 -05:00
|
|
|
*/
|
2004-07-02 15:02:00 -04:00
|
|
|
public static DisplayMode[] getAvailableDisplayModes() {
|
|
|
|
DisplayMode[] unfilteredModes = nGetAvailableDisplayModes();
|
|
|
|
|
|
|
|
if (unfilteredModes == null) {
|
|
|
|
return new DisplayMode[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
// We'll use a HashSet to filter out the duplicated modes
|
|
|
|
HashSet modes = new HashSet(unfilteredModes.length);
|
|
|
|
|
|
|
|
modes.addAll(Arrays.asList(unfilteredModes));
|
|
|
|
DisplayMode[] filteredModes = new DisplayMode[modes.size()];
|
|
|
|
modes.toArray(filteredModes);
|
|
|
|
|
|
|
|
Sys.log("Removed " + (unfilteredModes.length - filteredModes.length) + " duplicate displaymodes");
|
|
|
|
|
|
|
|
return filteredModes;
|
2004-04-03 18:01:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2004-07-02 15:02:00 -04:00
|
|
|
* Native method for getting displaymodes
|
2004-04-03 18:01:39 -05:00
|
|
|
*/
|
2004-07-02 15:02:00 -04:00
|
|
|
private static native DisplayMode[] nGetAvailableDisplayModes();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the current display mode, as set by setDisplayMode().
|
|
|
|
* @return The current display mode
|
|
|
|
*/
|
|
|
|
public static DisplayMode getDisplayMode() {
|
|
|
|
return current_mode;
|
2004-04-03 18:01:39 -05:00
|
|
|
}
|
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
2004-07-02 15:02:00 -04:00
|
|
|
* Set the current display mode. If no OpenGL context has been created, the given mode will apply to
|
|
|
|
* the context when create() is called, and no immediate mode switching will happen. If there is a
|
|
|
|
* context already, it will be resized according to the given mode. If the context is also a
|
2004-07-03 09:55:25 -04:00
|
|
|
* fullscreen context, the mode will also be switched immediately. The native cursor position
|
|
|
|
* is also reset.
|
2004-07-02 15:02:00 -04:00
|
|
|
*
|
|
|
|
* @param mode The new display mode to set
|
|
|
|
* @throws LWJGLException if the display mode could not be set
|
2003-03-27 17:32:48 -05:00
|
|
|
*/
|
2004-07-02 15:02:00 -04:00
|
|
|
public static void setDisplayMode(DisplayMode mode) throws LWJGLException {
|
2004-07-03 09:02:45 -04:00
|
|
|
if (mode == null)
|
|
|
|
throw new NullPointerException("mode must be non-null");
|
2004-07-02 15:02:00 -04:00
|
|
|
current_mode = mode;
|
|
|
|
if (isCreated()) {
|
|
|
|
destroyWindow();
|
|
|
|
if (fullscreen)
|
|
|
|
switchDisplayMode(current_mode);
|
|
|
|
createWindow();
|
|
|
|
}
|
2003-03-27 17:32:48 -05:00
|
|
|
}
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
2004-07-02 15:02:00 -04:00
|
|
|
* Create the native window peer from the given mode and fullscreen flag.
|
|
|
|
* A native context must exist, and it will be attached to the window.
|
2003-03-27 17:32:48 -05:00
|
|
|
*/
|
2004-07-02 15:02:00 -04:00
|
|
|
private static void createWindow() throws LWJGLException {
|
|
|
|
nCreateWindow(current_mode, fullscreen);
|
2004-07-03 06:16:28 -04:00
|
|
|
if (title != null)
|
|
|
|
nSetTitle(title);
|
2004-07-02 15:02:00 -04:00
|
|
|
initControls();
|
2004-07-03 13:39:25 -04:00
|
|
|
nSetVSyncEnabled(vsync);
|
2004-07-02 15:02:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
private static native void nCreateWindow(DisplayMode mode, boolean fullscreen) throws LWJGLException;
|
|
|
|
|
|
|
|
private static void destroyWindow() {
|
|
|
|
// Automatically destroy keyboard, mouse, and controller
|
2004-07-03 09:55:25 -04:00
|
|
|
if (Mouse.isCreated()) {
|
2004-07-02 15:02:00 -04:00
|
|
|
Mouse.destroy();
|
|
|
|
}
|
2004-07-03 09:55:25 -04:00
|
|
|
if (Keyboard.isCreated()) {
|
2004-07-02 15:02:00 -04:00
|
|
|
Keyboard.destroy();
|
|
|
|
}
|
2004-07-03 09:55:25 -04:00
|
|
|
if (Controller.isCreated()) {
|
2004-07-02 15:02:00 -04:00
|
|
|
Controller.destroy();
|
|
|
|
}
|
|
|
|
nDestroyWindow();
|
|
|
|
}
|
|
|
|
|
|
|
|
private static native void nDestroyWindow();
|
|
|
|
|
|
|
|
private static native void switchDisplayMode(DisplayMode mode) throws LWJGLException;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reset the display mode to whatever it was when LWJGL was initialized.
|
|
|
|
* Fails silently.
|
|
|
|
*/
|
|
|
|
private static native void resetDisplayMode();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the display configuration to the specified gamma, brightness and contrast.
|
|
|
|
* The configuration changes will be reset when resetDisplayMode is called.
|
|
|
|
*
|
|
|
|
* @param gamma The gamma value
|
|
|
|
* @param brightness The brightness value between -1.0 and 1.0, inclusive
|
|
|
|
* @param contrast The contrast, larger than 0.0.
|
|
|
|
*/
|
|
|
|
public static void setDisplayConfiguration(float gamma, float brightness, float contrast) throws LWJGLException {
|
|
|
|
if (brightness < -1.0f || brightness > 1.0f)
|
|
|
|
throw new IllegalArgumentException("Invalid brightness value");
|
|
|
|
if (contrast < 0.0f)
|
|
|
|
throw new IllegalArgumentException("Invalid contrast value");
|
|
|
|
int rampSize = getGammaRampLength();
|
|
|
|
if (rampSize == 0) {
|
|
|
|
throw new LWJGLException("Display configuration not supported");
|
|
|
|
}
|
|
|
|
FloatBuffer gammaRamp = ByteBuffer.allocateDirect(rampSize*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
|
|
|
for (int i = 0; i < rampSize; i++) {
|
|
|
|
float intensity = (float)i/(rampSize - 1);
|
|
|
|
// apply gamma
|
|
|
|
float rampEntry = (float)java.lang.Math.pow(intensity, gamma);
|
|
|
|
// apply brightness
|
|
|
|
rampEntry += brightness;
|
|
|
|
// apply contrast
|
|
|
|
rampEntry = (rampEntry - 0.5f)*contrast + 0.5f;
|
|
|
|
// Clamp entry to [0, 1]
|
|
|
|
if (rampEntry > 1.0f)
|
|
|
|
rampEntry = 1.0f;
|
|
|
|
else if (rampEntry < 0.0f)
|
|
|
|
rampEntry = 0.0f;
|
|
|
|
gammaRamp.put(i, rampEntry);
|
|
|
|
}
|
|
|
|
setGammaRamp(gammaRamp);
|
|
|
|
Sys.log("Gamma set, gamma = " + gamma + ", brightness = " + brightness + ", contrast = " + contrast);
|
2003-03-27 17:32:48 -05:00
|
|
|
}
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2004-07-02 15:02:00 -04:00
|
|
|
/**
|
|
|
|
* Return the length of the gamma ramp arrays. Returns 0 if gamma settings are
|
|
|
|
* unsupported.
|
|
|
|
*
|
|
|
|
* @return the length of each gamma ramp array, or 0 if gamma settings are unsupported.
|
|
|
|
*/
|
|
|
|
private static native int getGammaRampLength();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Native method to set the gamma ramp.
|
|
|
|
*/
|
|
|
|
private static native void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the driver adapter string. This is a unique string describing the actual card's hardware, eg. "Geforce2", "PS2",
|
|
|
|
* "Radeon9700". If the adapter cannot be determined, this function returns null.
|
|
|
|
* @return a String
|
|
|
|
*/
|
|
|
|
public static native String getAdapter();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the driver version. This is a vendor/adapter specific version string. If the version cannot be determined,
|
|
|
|
* this function returns null.
|
|
|
|
* @return a String
|
|
|
|
*/
|
|
|
|
public static native String getVersion();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Synchronize the display to a capped frame rate.
|
|
|
|
* @param fps The desired frame rate, in frames per second
|
|
|
|
*/
|
|
|
|
public static void sync(int fps) {
|
|
|
|
float frameTime = 1.0f / (float) fps;
|
|
|
|
timeNow = Sys.getTime();
|
|
|
|
while (timeNow > timeThen && (float) (timeNow - timeThen) / (float) Sys.getTimerResolution() < frameTime) {
|
|
|
|
// This is a system-friendly way of allowing other stuff to use CPU if it wants to
|
|
|
|
Thread.yield();
|
|
|
|
timeNow = Sys.getTime();
|
|
|
|
}
|
|
|
|
timeThen = timeNow;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize and return the current display mode.
|
|
|
|
*/
|
|
|
|
private static native DisplayMode init();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the X coordinate of the window (always 0 for fullscreen)
|
|
|
|
*/
|
|
|
|
/* public static int getX() {
|
|
|
|
if (!isCreated())
|
|
|
|
throw new IllegalStateException("Cannot get X on uncreated window");
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* @return the Y coordinate of the window (always 0 for fullscreen)
|
|
|
|
*/
|
|
|
|
/* public static int getY() {
|
|
|
|
if (!isCreated())
|
|
|
|
throw new IllegalStateException("Cannot get Y on uncreated window");
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
|
|
|
* @return the title of the window
|
|
|
|
*/
|
2003-08-02 13:11:33 -04:00
|
|
|
public static String getTitle() {
|
2004-03-27 06:55:07 -05:00
|
|
|
if (!isCreated())
|
|
|
|
throw new IllegalStateException("Cannot get title on uncreated window");
|
2003-03-27 17:32:48 -05:00
|
|
|
return title;
|
|
|
|
}
|
2004-07-02 15:02:00 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the fullscreen mode of the context. If no context has been created through create(),
|
|
|
|
* the mode will apply when create() is called. If fullscreen is true, the context will become
|
|
|
|
* a fullscreen context and the display mode is switched to the mode given by getDisplayMode(). If
|
|
|
|
* fullscreen is false, the context will become a windowed context with the dimensions given in the
|
2004-07-03 09:55:25 -04:00
|
|
|
* mode returned by getDisplayMode(). The native cursor position is also reset.
|
2004-07-02 15:02:00 -04:00
|
|
|
*
|
|
|
|
* @param fullscreen Specify the fullscreen mode of the context.
|
|
|
|
*/
|
|
|
|
public static void setFullscreen(boolean fullscreen) throws LWJGLException {
|
|
|
|
if (Display.fullscreen != fullscreen) {
|
|
|
|
Display.fullscreen = fullscreen;
|
2004-07-03 12:41:38 -04:00
|
|
|
if (!isCreated())
|
2004-07-02 15:02:00 -04:00
|
|
|
return;
|
|
|
|
destroyWindow();
|
|
|
|
if (fullscreen) {
|
|
|
|
try {
|
|
|
|
switchDisplayMode(current_mode);
|
|
|
|
} catch (LWJGLException e) {
|
|
|
|
destroyContext();
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
resetDisplayMode();
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
createWindow();
|
|
|
|
} catch (LWJGLException e) {
|
|
|
|
destroyContext();
|
|
|
|
if (fullscreen)
|
|
|
|
resetDisplayMode();
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-09-26 09:59:50 -04:00
|
|
|
/**
|
2004-07-02 15:02:00 -04:00
|
|
|
* @return whether the Display is in fullscreen mode
|
2003-09-26 09:59:50 -04:00
|
|
|
*/
|
|
|
|
public static boolean isFullscreen() {
|
|
|
|
return fullscreen;
|
|
|
|
}
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
|
|
|
* Set the title of the window. This may be ignored by the underlying OS.
|
|
|
|
* @param newTitle The new window title
|
|
|
|
*/
|
2003-08-02 13:11:33 -04:00
|
|
|
public static void setTitle(String newTitle) {
|
2003-03-27 17:32:48 -05:00
|
|
|
title = newTitle;
|
2004-07-03 06:16:28 -04:00
|
|
|
if (isCreated())
|
|
|
|
nSetTitle(title);
|
2003-03-27 17:32:48 -05:00
|
|
|
}
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
|
|
|
* Native implementation of setTitle(). This will read the window's title member
|
|
|
|
* and stash it in the native title of the window.
|
|
|
|
*/
|
2003-08-02 13:11:33 -04:00
|
|
|
private static native void nSetTitle(String title);
|
2003-03-27 17:32:48 -05:00
|
|
|
|
2003-07-28 06:09:58 -04:00
|
|
|
/**
|
|
|
|
* @return true if the user or operating system has asked the window to close
|
|
|
|
*/
|
2003-08-02 13:11:33 -04:00
|
|
|
public static boolean isCloseRequested() {
|
2004-03-27 06:55:07 -05:00
|
|
|
if (!isCreated())
|
|
|
|
throw new IllegalStateException("Cannot determine close requested state of uncreated window");
|
2003-10-01 05:33:22 -04:00
|
|
|
return nIsCloseRequested();
|
2003-07-28 06:09:58 -04:00
|
|
|
}
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2003-08-04 06:09:40 -04:00
|
|
|
private static native boolean nIsCloseRequested();
|
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
2004-04-04 08:53:45 -04:00
|
|
|
* @return true if the window is visible, false if not
|
2003-03-27 17:32:48 -05:00
|
|
|
*/
|
2004-04-04 08:53:45 -04:00
|
|
|
public static boolean isVisible() {
|
2004-03-27 06:55:07 -05:00
|
|
|
if (!isCreated())
|
|
|
|
throw new IllegalStateException("Cannot determine minimized state of uncreated window");
|
2004-04-04 08:53:45 -04:00
|
|
|
return nIsVisible();
|
2003-03-27 17:32:48 -05:00
|
|
|
}
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2004-04-04 08:53:45 -04:00
|
|
|
private static native boolean nIsVisible();
|
2003-08-04 06:09:40 -04:00
|
|
|
|
2003-07-28 06:09:58 -04:00
|
|
|
/**
|
2004-04-04 08:53:45 -04:00
|
|
|
* @return true if window is active, that is, the foreground display of the operating system.
|
2003-07-28 06:09:58 -04:00
|
|
|
*/
|
2004-04-04 08:53:45 -04:00
|
|
|
public static boolean isActive() {
|
2004-03-27 06:55:07 -05:00
|
|
|
if (!isCreated())
|
|
|
|
throw new IllegalStateException("Cannot determine focused state of uncreated window");
|
2004-04-04 08:53:45 -04:00
|
|
|
return nIsActive();
|
2003-07-28 06:09:58 -04:00
|
|
|
}
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2004-04-04 08:53:45 -04:00
|
|
|
private static native boolean nIsActive();
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
|
|
|
* 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
|
2004-04-04 10:10:19 -04:00
|
|
|
* redraw when it returns true. The flag is cleared when update() or isDirty() is called.
|
2004-04-03 16:05:57 -05:00
|
|
|
*
|
2003-03-27 17:32:48 -05:00
|
|
|
* @return true if the window has been damaged by external changes
|
|
|
|
* and needs to repaint itself
|
|
|
|
*/
|
2003-08-02 13:11:33 -04:00
|
|
|
public static boolean isDirty() {
|
2004-03-27 06:55:07 -05:00
|
|
|
if (!isCreated())
|
|
|
|
throw new IllegalStateException("Cannot determine dirty state of uncreated window");
|
2003-08-04 06:09:40 -04:00
|
|
|
return nIsDirty();
|
2003-03-27 17:32:48 -05:00
|
|
|
}
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2003-08-04 06:09:40 -04:00
|
|
|
private static native boolean nIsDirty();
|
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
2004-03-26 06:01:34 -05:00
|
|
|
* Update the window. This processes operating system events, and if the window is visible
|
|
|
|
* clears the dirty flag and swaps the buffers.
|
|
|
|
* @throws OpenGLException if an OpenGL error has occured since the last call to GL11.glGetError()
|
2003-03-27 17:32:48 -05:00
|
|
|
*/
|
2004-03-26 06:01:34 -05:00
|
|
|
public static void update() {
|
2004-03-27 06:55:07 -05:00
|
|
|
if (!isCreated())
|
2004-03-28 15:29:52 -05:00
|
|
|
throw new IllegalStateException("Cannot update uncreated window");
|
2004-04-04 09:19:54 -04:00
|
|
|
|
2004-04-04 09:39:10 -04:00
|
|
|
// We paint only when the window is visible or dirty
|
|
|
|
if (isVisible() || isDirty()) {
|
2004-03-26 06:01:34 -05:00
|
|
|
Util.checkGLError();
|
|
|
|
swapBuffers();
|
|
|
|
}
|
2004-04-04 09:39:10 -04:00
|
|
|
|
|
|
|
nUpdate();
|
|
|
|
|
2004-03-26 06:01:34 -05:00
|
|
|
// Poll the input devices while we're here
|
|
|
|
if (Mouse.isCreated()) {
|
|
|
|
Mouse.poll();
|
|
|
|
Mouse.updateCursor();
|
|
|
|
}
|
|
|
|
if (Keyboard.isCreated()) {
|
|
|
|
Keyboard.poll();
|
|
|
|
}
|
|
|
|
if (Controller.isCreated()) {
|
|
|
|
Controller.poll();
|
|
|
|
}
|
2003-03-27 17:32:48 -05:00
|
|
|
}
|
2003-03-30 14:26:39 -05:00
|
|
|
|
2003-03-28 14:02:24 -05:00
|
|
|
/**
|
2003-08-03 18:05:40 -04:00
|
|
|
* Swap double buffers.
|
2003-03-28 14:02:24 -05:00
|
|
|
*/
|
2003-08-03 18:05:40 -04:00
|
|
|
private static native void swapBuffers();
|
2004-04-03 16:05:57 -05:00
|
|
|
|
2004-02-18 12:48:26 -05:00
|
|
|
/**
|
2004-07-02 15:02:00 -04:00
|
|
|
* Make the Display the current rendering context for GL calls.
|
2004-02-18 12:48:26 -05:00
|
|
|
*/
|
|
|
|
public static synchronized void makeCurrent() {
|
2004-03-27 06:55:07 -05:00
|
|
|
if (!isCreated())
|
|
|
|
throw new IllegalStateException("No window created to make current");
|
2004-02-18 12:48:26 -05:00
|
|
|
nMakeCurrent();
|
2004-02-24 09:31:39 -05:00
|
|
|
GLContext.useContext(context);
|
2004-02-18 12:48:26 -05:00
|
|
|
}
|
2004-04-03 16:05:57 -05:00
|
|
|
|
2004-02-18 12:48:26 -05:00
|
|
|
/**
|
|
|
|
* Make the window the current rendering context for GL calls.
|
|
|
|
*/
|
|
|
|
private static native void nMakeCurrent();
|
2004-07-02 15:02:00 -04:00
|
|
|
|
2004-03-26 06:01:34 -05:00
|
|
|
/**
|
2004-07-02 15:02:00 -04:00
|
|
|
* Create the OpenGL context. If isFullscreen() is true or if windowed
|
|
|
|
* context are not supported on the platform, the display mode will be switched to the mode returned by
|
|
|
|
* getDisplayMode(), and a fullscreen context will be created. If isFullscreen() is false, a windowed context
|
|
|
|
* will be created with the dimensions given in the mode returned by getDisplayMode(). If a context can't be
|
|
|
|
* created with the given parameters, a LWJGLException will be thrown.
|
|
|
|
*
|
2004-03-26 06:09:39 -05:00
|
|
|
* <p>The window created will be set up in orthographic 2D projection, with 1:1 pixel ratio with GL coordinates.
|
2004-07-02 15:02:00 -04:00
|
|
|
*
|
2004-03-27 10:05:24 -05:00
|
|
|
* @throws LWJGLException
|
2004-03-26 06:01:34 -05:00
|
|
|
*/
|
2004-07-02 15:02:00 -04:00
|
|
|
public static void create() throws LWJGLException {
|
|
|
|
create(new PixelFormat());
|
2004-03-26 06:01:34 -05:00
|
|
|
}
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2004-03-26 06:01:34 -05:00
|
|
|
/**
|
2004-07-02 15:02:00 -04:00
|
|
|
* Create the OpenGL context with the given minimum parameters. If isFullscreen() is true or if windowed
|
|
|
|
* context are not supported on the platform, the display mode will be switched to the mode returned by
|
|
|
|
* getDisplayMode(), and a fullscreen context will be created. If isFullscreen() is false, a windowed context
|
|
|
|
* will be created with the dimensions given in the mode returned by getDisplayMode(). If a context can't be
|
|
|
|
* created with the given parameters, a LWJGLException will be thrown.
|
|
|
|
*
|
2004-03-26 06:09:39 -05:00
|
|
|
* <p>The window created will be set up in orthographic 2D projection, with 1:1 pixel ratio with GL coordinates.
|
2004-07-02 15:02:00 -04:00
|
|
|
*
|
|
|
|
* @param pixel_format Describes the minimum specifications the context must fulfill.
|
|
|
|
* @throws LWJGLException
|
|
|
|
*/
|
|
|
|
public static void create(PixelFormat pixel_format) throws LWJGLException {
|
2004-04-04 09:01:53 -04:00
|
|
|
if (isCreated())
|
2004-07-02 15:02:00 -04:00
|
|
|
throw new IllegalStateException("Only one LWJGL context may be instantiated at any one time.");
|
|
|
|
if (fullscreen)
|
|
|
|
switchDisplayMode(current_mode);
|
|
|
|
createContext(pixel_format);
|
|
|
|
context = new Display();
|
|
|
|
try {
|
|
|
|
createWindow();
|
|
|
|
} catch (LWJGLException e) {
|
|
|
|
destroyContext();
|
|
|
|
context = null;
|
|
|
|
if (fullscreen)
|
|
|
|
resetDisplayMode();
|
2004-07-03 12:07:00 -04:00
|
|
|
throw e;
|
2004-07-02 15:02:00 -04:00
|
|
|
}
|
|
|
|
makeCurrent();
|
|
|
|
initContext();
|
2003-08-03 18:05:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2004-07-02 15:02:00 -04:00
|
|
|
* Create the native OpenGL context.
|
2004-03-27 10:05:24 -05:00
|
|
|
* @throws LWJGLException
|
2003-03-28 14:02:24 -05:00
|
|
|
*/
|
2004-07-02 15:02:00 -04:00
|
|
|
private static native void createContext(PixelFormat pixel_format) throws LWJGLException;
|
|
|
|
|
|
|
|
private static native void destroyContext();
|
2004-03-26 06:09:39 -05:00
|
|
|
|
2004-07-02 15:02:00 -04:00
|
|
|
private static void initContext() {
|
2004-03-26 06:09:39 -05:00
|
|
|
// Put the window into orthographic projection mode with 1:1 pixel ratio.
|
|
|
|
// We haven't used GLU here to do this to avoid an unnecessary dependency.
|
|
|
|
GL11.glMatrixMode(GL11.GL_PROJECTION);
|
|
|
|
GL11.glLoadIdentity();
|
2004-07-02 15:02:00 -04:00
|
|
|
GL11.glOrtho(0.0, (double) current_mode.getWidth(), 0.0, (double) current_mode.getHeight(), -1.0, 1.0);
|
2004-03-26 06:09:39 -05:00
|
|
|
GL11.glMatrixMode(GL11.GL_MODELVIEW);
|
|
|
|
GL11.glLoadIdentity();
|
2004-07-02 15:02:00 -04:00
|
|
|
GL11.glViewport(0, 0, current_mode.getWidth(), current_mode.getHeight());
|
|
|
|
}
|
2004-03-26 06:09:39 -05:00
|
|
|
|
2004-07-02 15:02:00 -04:00
|
|
|
private static void initControls() {
|
2004-03-26 06:01:34 -05:00
|
|
|
// Automatically create mouse, keyboard and controller
|
2004-07-03 09:13:54 -04:00
|
|
|
if (!Boolean.getBoolean("org.lwjgl.opengl.Display.noinput")) {
|
2004-07-02 15:02:00 -04:00
|
|
|
if (!Mouse.isCreated() && !Boolean.getBoolean("org.lwjgl.opengl.Display.nomouse")) {
|
2004-04-03 16:05:57 -05:00
|
|
|
try {
|
|
|
|
Mouse.create();
|
|
|
|
Mouse.enableBuffer();
|
|
|
|
} catch (LWJGLException e) {
|
|
|
|
if (Sys.DEBUG) {
|
|
|
|
e.printStackTrace(System.err);
|
|
|
|
} else {
|
|
|
|
Sys.log("Failed to create Mouse: "+e);
|
|
|
|
}
|
2004-03-26 06:01:34 -05:00
|
|
|
}
|
|
|
|
}
|
2004-07-02 15:02:00 -04:00
|
|
|
if (!Keyboard.isCreated() && !Boolean.getBoolean("org.lwjgl.opengl.Display.nokeyboard")) {
|
2004-04-03 16:05:57 -05:00
|
|
|
try {
|
|
|
|
Keyboard.create();
|
|
|
|
Keyboard.enableBuffer();
|
|
|
|
Keyboard.enableTranslation();
|
|
|
|
} catch (LWJGLException e) {
|
|
|
|
if (Sys.DEBUG) {
|
|
|
|
e.printStackTrace(System.err);
|
|
|
|
} else {
|
|
|
|
Sys.log("Failed to create Keyboard: "+e);
|
|
|
|
}
|
2004-03-26 06:01:34 -05:00
|
|
|
}
|
|
|
|
}
|
2004-07-02 15:02:00 -04:00
|
|
|
if (!Controller.isCreated() && !Boolean.getBoolean("org.lwjgl.opengl.Display.nocontroller")) {
|
2004-04-03 16:05:57 -05:00
|
|
|
try {
|
|
|
|
Controller.create();
|
|
|
|
} catch (LWJGLException e) {
|
|
|
|
if (Sys.DEBUG) {
|
|
|
|
e.printStackTrace(System.err);
|
|
|
|
} else {
|
|
|
|
Sys.log("Failed to create Controller: "+e);
|
|
|
|
}
|
2004-03-26 06:01:34 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-08-04 19:00:49 -04:00
|
|
|
}
|
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
2004-07-02 15:02:00 -04:00
|
|
|
* Destroy the Display. After this call, there will be no current GL rendering context,
|
|
|
|
* regardless of whether the Display was the current rendering context.
|
2003-03-27 17:32:48 -05:00
|
|
|
*/
|
2004-02-18 12:48:26 -05:00
|
|
|
public static synchronized void destroy() {
|
2004-07-02 15:02:00 -04:00
|
|
|
if (!isCreated()) {
|
2003-03-28 14:02:24 -05:00
|
|
|
return;
|
2004-02-18 12:48:26 -05:00
|
|
|
}
|
2004-04-03 16:05:57 -05:00
|
|
|
|
2004-07-02 15:02:00 -04:00
|
|
|
destroyWindow();
|
|
|
|
destroyContext();
|
2003-11-03 06:23:56 -05:00
|
|
|
context = null;
|
2004-07-03 13:39:25 -04:00
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reset display mode if fullscreen. This method is also called from the shutdown hook added in Sys
|
|
|
|
*/
|
|
|
|
private static void reset() {
|
2004-07-02 15:02:00 -04:00
|
|
|
if (fullscreen)
|
|
|
|
resetDisplayMode();
|
2003-11-03 06:23:56 -05:00
|
|
|
}
|
2004-04-03 16:05:57 -05:00
|
|
|
|
2003-11-03 06:23:56 -05:00
|
|
|
/**
|
2004-07-02 15:02:00 -04:00
|
|
|
* @return the unique DIsplay context (or null, if the Display has not been created)
|
2003-11-03 06:23:56 -05:00
|
|
|
*/
|
2004-02-23 11:30:48 -05:00
|
|
|
public static Object getContext() {
|
2003-11-03 06:23:56 -05:00
|
|
|
return context;
|
2003-03-27 17:46:25 -05:00
|
|
|
}
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2003-03-27 18:01:14 -05:00
|
|
|
/**
|
2003-03-28 14:02:24 -05:00
|
|
|
* @return true if the window's native peer has been created
|
2003-03-27 18:01:14 -05:00
|
|
|
*/
|
2003-08-02 13:11:33 -04:00
|
|
|
public static boolean isCreated() {
|
2004-02-18 12:48:26 -05:00
|
|
|
return context != null;
|
2003-03-27 18:01:14 -05:00
|
|
|
}
|
2003-08-03 18:05:40 -04:00
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
/**
|
2003-08-17 05:27:32 -04:00
|
|
|
* Updates the windows internal state. This must be called at least once per video frame
|
2003-03-27 17:32:48 -05:00
|
|
|
* to handle window close requests, moves, paints, etc.
|
|
|
|
*/
|
2004-03-26 06:01:34 -05:00
|
|
|
private static native void nUpdate();
|
2003-10-20 10:17:47 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Enable or disable vertical monitor synchronization. This call is a best-attempt at changing
|
|
|
|
* the vertical refresh synchronization of the monitor, and is not guaranteed to be successful.
|
|
|
|
* @param sync true to synchronize; false to ignore synchronization
|
|
|
|
*/
|
|
|
|
public static void setVSyncEnabled(boolean sync) {
|
2004-07-03 13:39:25 -04:00
|
|
|
vsync = sync;
|
|
|
|
if (isCreated())
|
|
|
|
nSetVSyncEnabled(vsync);
|
2003-10-20 10:17:47 -04:00
|
|
|
}
|
|
|
|
|
2003-11-25 17:34:04 -05:00
|
|
|
private static native void nSetVSyncEnabled(boolean sync);
|
2004-04-03 16:05:57 -05:00
|
|
|
|
2004-04-04 08:53:45 -04:00
|
|
|
// /**
|
|
|
|
// * Set the window's location. This is a no-op on fullscreen windows.
|
|
|
|
// * The window is clamped to remain entirely on the screen. If you attempt
|
|
|
|
// * to position the window such that it would extend off the screen, the window
|
|
|
|
// * is simply placed as close to the edge as possible.
|
|
|
|
// * @param x, y The new window location
|
|
|
|
// */
|
|
|
|
// public static void setLocation(int x, int y) {
|
|
|
|
// if (!isCreated())
|
|
|
|
// throw new IllegalStateException("Cannot move uncreated window");
|
|
|
|
// if (fullscreen) {
|
|
|
|
// return;
|
|
|
|
// }
|
2004-07-02 15:02:00 -04:00
|
|
|
// Display.x = Math.max(0, Math.min(Display.getWidth() - Display.width, x));
|
|
|
|
// Display.y = Math.max(0, Math.min(Display.getHeight() - Display.height, y));
|
|
|
|
// nReshape(Display.x, Display.y, Display.width, Display.height);
|
2004-04-04 08:53:45 -04:00
|
|
|
// }
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// /**
|
|
|
|
// * Native method to reshape the window
|
|
|
|
// * @param x, y The new window location
|
|
|
|
// * @param width, height The new window dimensions
|
|
|
|
// */
|
|
|
|
// private static native void nReshape(int x, int y, int width, int height);
|
2004-04-03 16:05:57 -05:00
|
|
|
|
2003-03-27 17:32:48 -05:00
|
|
|
}
|