Remove a lot of synchronization
This commit is contained in:
parent
68d112adec
commit
4f7fee2ed4
78
build.xml
78
build.xml
|
@ -71,10 +71,43 @@
|
||||||
<antcall target="-distribute" />
|
<antcall target="-distribute" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="all" description="Creates the Java archives and the natives for the current platform" depends="jars, compile_native"/>
|
<target name="all" description="Creates the Java archives and the natives for the current platform">
|
||||||
|
<parallel>
|
||||||
|
<antcall target="jars" />
|
||||||
|
<antcall target="compile_native" />
|
||||||
|
</parallel>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jars+lwjgl+NoDeps" depends="-initialize">
|
||||||
|
<jar destfile="${lwjgl.target.jars}/lwjgl.jar" taskname="lwjgl.jar">
|
||||||
|
<fileset refid="lwjgl.fileset" />
|
||||||
|
<fileset refid="lwjgl.fileset.dependencies"/>
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Sealed" value="true"/>
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jars+lwjgl_util+NoDeps" depends="-initialize">
|
||||||
|
<jar destfile="${lwjgl.target.jars}/lwjgl_util.jar" taskname="lwjgl_util.jar">
|
||||||
|
<fileset refid="lwjgl_util.fileset" />
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jars+lwjgl_test+NoDeps" depends="-initialize">
|
||||||
|
<jar destfile="${lwjgl.target.jars}/lwjgl_test.jar" taskname="lwjgl_test.jar">
|
||||||
|
<fileset refid="lwjgl_test.fileset" />
|
||||||
|
<fileset refid="lwjgl_test_extra.fileset" />
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
<!-- Create ONLY the jar archives -->
|
<!-- Create ONLY the jar archives -->
|
||||||
<target name="jars+NoDeps" description="Creates the Java archives ONLY and places them in libs/" depends="-createjars">
|
<target name="jars+NoDeps" description="Creates the Java archives ONLY and places them in libs/" depends="-initialize">
|
||||||
|
<parallel>
|
||||||
|
<antcall target="jars+lwjgl+NoDeps" />
|
||||||
|
<antcall target="jars+lwjgl_util+NoDeps" />
|
||||||
|
<antcall target="jars+lwjgl_test+NoDeps" />
|
||||||
|
</parallel>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="jars" description="Creates the Java archives ONLY and places them in libs/" depends="generate-all, compile, jars+NoDeps">
|
<target name="jars" description="Creates the Java archives ONLY and places them in libs/" depends="generate-all, compile, jars+NoDeps">
|
||||||
|
@ -97,29 +130,6 @@
|
||||||
</jar>
|
</jar>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<!-- Packages the java files -->
|
|
||||||
<target name="-createjars" depends="-initialize">
|
|
||||||
<!-- Create lwjgl.jar -->
|
|
||||||
<jar destfile="${lwjgl.target.jars}/lwjgl.jar" taskname="lwjgl.jar">
|
|
||||||
<fileset refid="lwjgl.fileset" />
|
|
||||||
<fileset refid="lwjgl.fileset.dependencies"/>
|
|
||||||
<manifest>
|
|
||||||
<attribute name="Sealed" value="true"/>
|
|
||||||
</manifest>
|
|
||||||
</jar>
|
|
||||||
|
|
||||||
<!-- Create lwjgl_test.jar -->
|
|
||||||
<jar destfile="${lwjgl.target.jars}/lwjgl_test.jar" taskname="lwjgl_test.jar">
|
|
||||||
<fileset refid="lwjgl_test.fileset" />
|
|
||||||
<fileset refid="lwjgl_test_extra.fileset" />
|
|
||||||
</jar>
|
|
||||||
|
|
||||||
<!-- Create lwjgl_util.jar -->
|
|
||||||
<jar destfile="${lwjgl.target.jars}/lwjgl_util.jar" taskname="lwjgl_util.jar">
|
|
||||||
<fileset refid="lwjgl_util.fileset" />
|
|
||||||
</jar>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<!-- Packages the java files for the ES build -->
|
<!-- Packages the java files for the ES build -->
|
||||||
<target name="-createjars_es">
|
<target name="-createjars_es">
|
||||||
<!-- ================================================================== -->
|
<!-- ================================================================== -->
|
||||||
|
@ -456,11 +466,11 @@
|
||||||
<src path="${lwjgl.target.gen.java}"/>
|
<src path="${lwjgl.target.gen.java}"/>
|
||||||
<exclude name="org/lwjgl/util/generator/**"/>
|
<exclude name="org/lwjgl/util/generator/**"/>
|
||||||
</javac>
|
</javac>
|
||||||
<javac debug="yes" srcdir="${lwjgl.src.java}" destdir="${lwjgl.target.gen.classes}" includes="org/lwjgl/test/**" source="1.8" target="1.8" taskname="test" />
|
<!--<javac debug="yes" srcdir="${lwjgl.src.java}" destdir="${lwjgl.target.gen.classes}" includes="org/lwjgl/test/**" source="1.8" target="1.8" taskname="test" />-->
|
||||||
<javac debug="yes" srcdir="${lwjgl.src.java}" destdir="${lwjgl.target.gen.classes}" includes="org/lwjgl/examples/**" source="1.8" target="1.8" taskname="examples" />
|
<!--<javac debug="yes" srcdir="${lwjgl.src.java}" destdir="${lwjgl.target.gen.classes}" includes="org/lwjgl/examples/**" source="1.8" target="1.8" taskname="examples" />-->
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="compile_native" depends="-initialize, compile, touch-version, version-mismatch" description="Compiles the native files">
|
<target name="compile_native" depends="-initialize, generate-all, touch-version, version-mismatch" description="Compiles the native files">
|
||||||
<condition property="lwjgl.platform.windows">
|
<condition property="lwjgl.platform.windows">
|
||||||
<os family="windows" />
|
<os family="windows" />
|
||||||
</condition>
|
</condition>
|
||||||
|
@ -528,7 +538,7 @@
|
||||||
<version-check platform="macosx"/>
|
<version-check platform="macosx"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="compile_native_es" depends="-initialize, compile, touch-version, version-mismatch" description="Compiles the native files">
|
<target name="compile_native_es" depends="-initialize, generate-all, touch-version, version-mismatch" description="Compiles the native files">
|
||||||
<condition property="lwjgl.platform.windows">
|
<condition property="lwjgl.platform.windows">
|
||||||
<os family="windows"/>
|
<os family="windows"/>
|
||||||
</condition>
|
</condition>
|
||||||
|
@ -597,24 +607,24 @@
|
||||||
</antcall>
|
</antcall>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="runtest" depends="all">
|
<target name="runtest">
|
||||||
<fail message="test.mainclass is not set. Use 'ant -Dtest.mainclass=<main-class> runtest'" unless="test.mainclass"/>
|
<fail message="test.mainclass is not set. Use 'ant -Dtest.mainclass=<main-class> runtest'" unless="test.mainclass"/>
|
||||||
<condition property="native_path" value="libs/windows">
|
<condition property="native_path" value="${lwjgl.target.natives}">
|
||||||
<os family="windows" />
|
<os family="windows" />
|
||||||
</condition>
|
</condition>
|
||||||
|
|
||||||
<condition property="native_path" value="libs/linux">
|
<condition property="native_path" value="${lwjgl.target.natives}">
|
||||||
<or>
|
<or>
|
||||||
<os name="Linux" />
|
<os name="Linux" />
|
||||||
<os name="SunOS" />
|
<os name="SunOS" />
|
||||||
</or>
|
</or>
|
||||||
</condition>
|
</condition>
|
||||||
|
|
||||||
<condition property="native_path" value="libs/macosx">
|
<condition property="native_path" value="${lwjgl.target.natives}">
|
||||||
<os name="Mac OS X" />
|
<os name="Mac OS X" />
|
||||||
</condition>
|
</condition>
|
||||||
<property name="native_path_expanded" location="${native_path}"/>
|
<property name="native_path_expanded" location="${native_path}"/>
|
||||||
<java classname="${test.mainclass}" classpath="res:${lwjgl.lib}/lwjgl.jar:${lwjgl.lib}/lwjgl_util.jar:${lwjgl.lib}/lwjgl_test.jar:${lwjgl.lib}/jinput.jar" fork="true">
|
<java classname="${test.mainclass}" classpath="res:${lwjgl.target.jars}/lwjgl.jar:${lwjgl.target.jars}/lwjgl_util.jar:${lwjgl.target.jars}/lwjgl_test.jar:${lwjgl.lib}/jinput.jar" fork="true">
|
||||||
<sysproperty key="org.lwjgl.util.Debug" value="true"/>
|
<sysproperty key="org.lwjgl.util.Debug" value="true"/>
|
||||||
<sysproperty key="java.library.path" value="${native_path_expanded}"/>
|
<sysproperty key="java.library.path" value="${native_path_expanded}"/>
|
||||||
<arg line="${args}"/>
|
<arg line="${args}"/>
|
||||||
|
|
|
@ -185,7 +185,7 @@
|
||||||
<include name="doc/README" />
|
<include name="doc/README" />
|
||||||
</patternset>
|
</patternset>
|
||||||
|
|
||||||
<uptodate property="lwjgl.main.built" targetfile="${lwjgl.lib}/windows/lwjgl.dll" >
|
<uptodate property="lwjgl.main.built" targetfile="${lwjgl.target.natives}/lwjgl.dll" >
|
||||||
<srcfiles dir= "${lwjgl.src.native}/common" includes="*.c*"/>
|
<srcfiles dir= "${lwjgl.src.native}/common" includes="*.c*"/>
|
||||||
<srcfiles dir= "${lwjgl.src.native}/windows" includes="*.c"/>
|
<srcfiles dir= "${lwjgl.src.native}/windows" includes="*.c"/>
|
||||||
</uptodate>
|
</uptodate>
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
java -cp res:target/jars/lwjgl.jar:target/jars/lwjgl_util.jar:target/jars/lwjgl_test.jar:lib/jinput.jar -Dorg.lwjgl.util.Debug=true -Djava.library.path=target/natives "$@"
|
|
@ -119,11 +119,9 @@ public class Cursor {
|
||||||
* @return the maximum size of a native cursor
|
* @return the maximum size of a native cursor
|
||||||
*/
|
*/
|
||||||
public static int getMinCursorSize() {
|
public static int getMinCursorSize() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!Mouse.isCreated())
|
||||||
if (!Mouse.isCreated())
|
throw new IllegalStateException("Mouse must be created.");
|
||||||
throw new IllegalStateException("Mouse must be created.");
|
return Mouse.getImplementation().getMinCursorSize();
|
||||||
return Mouse.getImplementation().getMinCursorSize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,11 +132,9 @@ public class Cursor {
|
||||||
* @return the maximum size of a native cursor
|
* @return the maximum size of a native cursor
|
||||||
*/
|
*/
|
||||||
public static int getMaxCursorSize() {
|
public static int getMaxCursorSize() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!Mouse.isCreated())
|
||||||
if (!Mouse.isCreated())
|
throw new IllegalStateException("Mouse must be created.");
|
||||||
throw new IllegalStateException("Mouse must be created.");
|
return Mouse.getImplementation().getMaxCursorSize();
|
||||||
return Mouse.getImplementation().getMaxCursorSize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -150,11 +146,10 @@ public class Cursor {
|
||||||
* @return A bit mask with native cursor capabilities.
|
* @return A bit mask with native cursor capabilities.
|
||||||
*/
|
*/
|
||||||
public static int getCapabilities() {
|
public static int getCapabilities() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (Mouse.getImplementation() != null) {
|
||||||
if (Mouse.getImplementation() != null)
|
return Mouse.getImplementation().getNativeCursorCapabilities();
|
||||||
return Mouse.getImplementation().getNativeCursorCapabilities();
|
} else {
|
||||||
else
|
return OpenGLPackageAccess.createImplementation().getNativeCursorCapabilities();
|
||||||
return OpenGLPackageAccess.createImplementation().getNativeCursorCapabilities();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -323,11 +323,9 @@ public class Keyboard {
|
||||||
* @throws LWJGLException if the keyboard could not be created for any reason
|
* @throws LWJGLException if the keyboard could not be created for any reason
|
||||||
*/
|
*/
|
||||||
public static void create() throws LWJGLException {
|
public static void create() throws LWJGLException {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!Display.isCreated()) throw new IllegalStateException("Display must be created.");
|
||||||
if (!Display.isCreated()) throw new IllegalStateException("Display must be created.");
|
|
||||||
|
|
||||||
create(OpenGLPackageAccess.createImplementation());
|
create(OpenGLPackageAccess.createImplementation());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void reset() {
|
private static void reset() {
|
||||||
|
@ -341,22 +339,19 @@ public class Keyboard {
|
||||||
* @return true if the keyboard has been created
|
* @return true if the keyboard has been created
|
||||||
*/
|
*/
|
||||||
public static boolean isCreated() {
|
public static boolean isCreated() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return created;
|
||||||
return created;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Destroy" the keyboard
|
* "Destroy" the keyboard
|
||||||
*/
|
*/
|
||||||
public static void destroy() {
|
public static void destroy() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!created) {
|
||||||
if (!created)
|
return;
|
||||||
return;
|
|
||||||
created = false;
|
|
||||||
implementation.destroyKeyboard();
|
|
||||||
reset();
|
|
||||||
}
|
}
|
||||||
|
created = false;
|
||||||
|
implementation.destroyKeyboard();
|
||||||
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -381,12 +376,11 @@ public class Keyboard {
|
||||||
* @see org.lwjgl.input.Keyboard#getEventCharacter()
|
* @see org.lwjgl.input.Keyboard#getEventCharacter()
|
||||||
*/
|
*/
|
||||||
public static void poll() {
|
public static void poll() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!created) {
|
||||||
if (!created)
|
throw new IllegalStateException("Keyboard must be created before you can poll the device");
|
||||||
throw new IllegalStateException("Keyboard must be created before you can poll the device");
|
|
||||||
implementation.pollKeyboard(keyDownBuffer);
|
|
||||||
read();
|
|
||||||
}
|
}
|
||||||
|
implementation.pollKeyboard(keyDownBuffer);
|
||||||
|
read();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void read() {
|
private static void read() {
|
||||||
|
@ -401,11 +395,10 @@ public class Keyboard {
|
||||||
* @return true if the key is down according to the last poll()
|
* @return true if the key is down according to the last poll()
|
||||||
*/
|
*/
|
||||||
public static boolean isKeyDown(int key) {
|
public static boolean isKeyDown(int key) {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!created) {
|
||||||
if (!created)
|
throw new IllegalStateException("Keyboard must be created before you can query key state");
|
||||||
throw new IllegalStateException("Keyboard must be created before you can query key state");
|
|
||||||
return keyDownBuffer.get(key) != 0;
|
|
||||||
}
|
}
|
||||||
|
return keyDownBuffer.get(key) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -425,7 +418,7 @@ public class Keyboard {
|
||||||
* @param key The key
|
* @param key The key
|
||||||
* @return a String with the key's human readable name in it or null if the key is unnamed
|
* @return a String with the key's human readable name in it or null if the key is unnamed
|
||||||
*/
|
*/
|
||||||
public static synchronized String getKeyName(int key) {
|
public static String getKeyName(int key) {
|
||||||
return keyName[key];
|
return keyName[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,12 +426,13 @@ public class Keyboard {
|
||||||
* Get's a key's index. If the key is unrecognised then KEY_NONE is returned.
|
* Get's a key's index. If the key is unrecognised then KEY_NONE is returned.
|
||||||
* @param keyName The key name
|
* @param keyName The key name
|
||||||
*/
|
*/
|
||||||
public static synchronized int getKeyIndex(String keyName) {
|
public static int getKeyIndex(String keyName) {
|
||||||
Integer ret = keyMap.get(keyName);
|
Integer ret = keyMap.get(keyName);
|
||||||
if (ret == null)
|
if (ret == null) {
|
||||||
return KEY_NONE;
|
return KEY_NONE;
|
||||||
else
|
} else {
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -446,16 +440,14 @@ public class Keyboard {
|
||||||
* @return the number of keyboard events
|
* @return the number of keyboard events
|
||||||
*/
|
*/
|
||||||
public static int getNumKeyboardEvents() {
|
public static int getNumKeyboardEvents() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!created)
|
||||||
if (!created)
|
throw new IllegalStateException("Keyboard must be created before you can read events");
|
||||||
throw new IllegalStateException("Keyboard must be created before you can read events");
|
int old_position = readBuffer.position();
|
||||||
int old_position = readBuffer.position();
|
int num_events = 0;
|
||||||
int num_events = 0;
|
while (readNext(tmp_event) && (!tmp_event.repeat || repeat_enabled))
|
||||||
while (readNext(tmp_event) && (!tmp_event.repeat || repeat_enabled))
|
num_events++;
|
||||||
num_events++;
|
readBuffer.position(old_position);
|
||||||
readBuffer.position(old_position);
|
return num_events;
|
||||||
return num_events;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -470,15 +462,12 @@ public class Keyboard {
|
||||||
* @return true if a keyboard event was read, false otherwise
|
* @return true if a keyboard event was read, false otherwise
|
||||||
*/
|
*/
|
||||||
public static boolean next() {
|
public static boolean next() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!created)
|
||||||
if (!created)
|
throw new IllegalStateException("Keyboard must be created before you can read events");
|
||||||
throw new IllegalStateException("Keyboard must be created before you can read events");
|
|
||||||
|
|
||||||
boolean result;
|
boolean result;
|
||||||
while ((result = readNext(current_event)) && current_event.repeat && !repeat_enabled)
|
while ((result = readNext(current_event)) && current_event.repeat && !repeat_enabled) {}
|
||||||
;
|
return result;
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -490,9 +479,7 @@ public class Keyboard {
|
||||||
* @see org.lwjgl.input.Keyboard#getEventKey()
|
* @see org.lwjgl.input.Keyboard#getEventKey()
|
||||||
*/
|
*/
|
||||||
public static void enableRepeatEvents(boolean enable) {
|
public static void enableRepeatEvents(boolean enable) {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
repeat_enabled = enable;
|
||||||
repeat_enabled = enable;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -502,9 +489,7 @@ public class Keyboard {
|
||||||
* @see org.lwjgl.input.Keyboard#getEventKey()
|
* @see org.lwjgl.input.Keyboard#getEventKey()
|
||||||
*/
|
*/
|
||||||
public static boolean areRepeatEventsEnabled() {
|
public static boolean areRepeatEventsEnabled() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return repeat_enabled;
|
||||||
return repeat_enabled;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean readNext(KeyEvent event) {
|
private static boolean readNext(KeyEvent event) {
|
||||||
|
@ -530,9 +515,7 @@ public class Keyboard {
|
||||||
* @return The character from the current event
|
* @return The character from the current event
|
||||||
*/
|
*/
|
||||||
public static char getEventCharacter() {
|
public static char getEventCharacter() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return (char)current_event.character;
|
||||||
return (char)current_event.character;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -543,9 +526,7 @@ public class Keyboard {
|
||||||
* @return The key from the current event
|
* @return The key from the current event
|
||||||
*/
|
*/
|
||||||
public static int getEventKey() {
|
public static int getEventKey() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return current_event.key;
|
||||||
return current_event.key;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -555,9 +536,7 @@ public class Keyboard {
|
||||||
* @return True if key was down, or false if released
|
* @return True if key was down, or false if released
|
||||||
*/
|
*/
|
||||||
public static boolean getEventKeyState() {
|
public static boolean getEventKeyState() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return current_event.state;
|
||||||
return current_event.state;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -568,9 +547,7 @@ public class Keyboard {
|
||||||
* @return The time in nanoseconds of the current event
|
* @return The time in nanoseconds of the current event
|
||||||
*/
|
*/
|
||||||
public static long getEventNanoseconds() {
|
public static long getEventNanoseconds() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return current_event.nanos;
|
||||||
return current_event.nanos;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -579,9 +556,7 @@ public class Keyboard {
|
||||||
* the current event is not a repeat even or if repeat events are disabled.
|
* the current event is not a repeat even or if repeat events are disabled.
|
||||||
*/
|
*/
|
||||||
public static boolean isRepeatEvent() {
|
public static boolean isRepeatEvent() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return current_event.repeat;
|
||||||
return current_event.repeat;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class KeyEvent {
|
private static final class KeyEvent {
|
||||||
|
|
|
@ -165,9 +165,7 @@ public class Mouse {
|
||||||
* @return the currently bound native cursor, if any.
|
* @return the currently bound native cursor, if any.
|
||||||
*/
|
*/
|
||||||
public static Cursor getNativeCursor() {
|
public static Cursor getNativeCursor() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return currentCursor;
|
||||||
return currentCursor;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -183,21 +181,20 @@ public class Mouse {
|
||||||
* @throws LWJGLException if the cursor could not be set for any reason
|
* @throws LWJGLException if the cursor could not be set for any reason
|
||||||
*/
|
*/
|
||||||
public static Cursor setNativeCursor(Cursor cursor) throws LWJGLException {
|
public static Cursor setNativeCursor(Cursor cursor) throws LWJGLException {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if ((Cursor.getCapabilities() & Cursor.CURSOR_ONE_BIT_TRANSPARENCY) == 0) {
|
||||||
if ((Cursor.getCapabilities() & Cursor.CURSOR_ONE_BIT_TRANSPARENCY) == 0)
|
throw new IllegalStateException("Mouse doesn't support native cursors");
|
||||||
throw new IllegalStateException("Mouse doesn't support native cursors");
|
|
||||||
Cursor oldCursor = currentCursor;
|
|
||||||
currentCursor = cursor;
|
|
||||||
if (isCreated()) {
|
|
||||||
if (currentCursor != null) {
|
|
||||||
implementation.setNativeCursor(currentCursor.getHandle());
|
|
||||||
currentCursor.setTimeout();
|
|
||||||
} else {
|
|
||||||
implementation.setNativeCursor(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return oldCursor;
|
|
||||||
}
|
}
|
||||||
|
Cursor oldCursor = currentCursor;
|
||||||
|
currentCursor = cursor;
|
||||||
|
if (isCreated()) {
|
||||||
|
if (currentCursor != null) {
|
||||||
|
implementation.setNativeCursor(currentCursor.getHandle());
|
||||||
|
currentCursor.setTimeout();
|
||||||
|
} else {
|
||||||
|
implementation.setNativeCursor(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return oldCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isClipMouseCoordinatesToWindow() {
|
public static boolean isClipMouseCoordinatesToWindow() {
|
||||||
|
@ -218,18 +215,16 @@ public class Mouse {
|
||||||
* to the window origin.
|
* to the window origin.
|
||||||
*/
|
*/
|
||||||
public static void setCursorPosition(int new_x, int new_y) {
|
public static void setCursorPosition(int new_x, int new_y) {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!isCreated()) {
|
||||||
if (!isCreated())
|
throw new IllegalStateException("Mouse is not created");
|
||||||
throw new IllegalStateException("Mouse is not created");
|
}
|
||||||
x = event_x = new_x;
|
x = event_x = new_x;
|
||||||
y = event_y = new_y;
|
y = event_y = new_y;
|
||||||
if (!isGrabbed() && (Cursor.getCapabilities() & Cursor.CURSOR_ONE_BIT_TRANSPARENCY) != 0) {
|
if (!isGrabbed() && (Cursor.getCapabilities() & Cursor.CURSOR_ONE_BIT_TRANSPARENCY) != 0) {
|
||||||
implementation.setCursorPosition(x, y);
|
implementation.setCursorPosition(x, y);
|
||||||
}
|
} else {
|
||||||
else {
|
grab_x = new_x;
|
||||||
grab_x = new_x;
|
grab_y = new_y;
|
||||||
grab_y = new_y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,34 +288,29 @@ public class Mouse {
|
||||||
* @throws LWJGLException if the mouse could not be created for any reason
|
* @throws LWJGLException if the mouse could not be created for any reason
|
||||||
*/
|
*/
|
||||||
public static void create() throws LWJGLException {
|
public static void create() throws LWJGLException {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!Display.isCreated()) throw new IllegalStateException("Display must be created.");
|
||||||
if (!Display.isCreated()) throw new IllegalStateException("Display must be created.");
|
|
||||||
|
|
||||||
create(OpenGLPackageAccess.createImplementation());
|
create(OpenGLPackageAccess.createImplementation());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the mouse has been created
|
* @return true if the mouse has been created
|
||||||
*/
|
*/
|
||||||
public static boolean isCreated() {
|
public static boolean isCreated() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return created;
|
||||||
return created;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Destroy" the mouse.
|
* "Destroy" the mouse.
|
||||||
*/
|
*/
|
||||||
public static void destroy() {
|
public static void destroy() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!created) return;
|
||||||
if (!created) return;
|
|
||||||
created = false;
|
|
||||||
buttons = null;
|
|
||||||
coord_buffer = null;
|
|
||||||
|
|
||||||
implementation.destroyMouse();
|
created = false;
|
||||||
}
|
buttons = null;
|
||||||
|
coord_buffer = null;
|
||||||
|
|
||||||
|
implementation.destroyMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -348,38 +338,37 @@ public class Mouse {
|
||||||
* @see org.lwjgl.input.Mouse#getDWheel()
|
* @see org.lwjgl.input.Mouse#getDWheel()
|
||||||
*/
|
*/
|
||||||
public static void poll() {
|
public static void poll() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!created) throw new IllegalStateException("Mouse must be created before you can poll it");
|
||||||
if (!created) throw new IllegalStateException("Mouse must be created before you can poll it");
|
|
||||||
implementation.pollMouse(coord_buffer, buttons);
|
|
||||||
|
|
||||||
/* If we're grabbed, poll returns mouse deltas, if not it returns absolute coordinates */
|
implementation.pollMouse(coord_buffer, buttons);
|
||||||
int poll_coord1 = coord_buffer.get(0);
|
|
||||||
int poll_coord2 = coord_buffer.get(1);
|
|
||||||
/* The wheel is always relative */
|
|
||||||
int poll_dwheel = coord_buffer.get(2);
|
|
||||||
|
|
||||||
if (isGrabbed()) {
|
/* If we're grabbed, poll returns mouse deltas, if not it returns absolute coordinates */
|
||||||
dx += poll_coord1;
|
int poll_coord1 = coord_buffer.get(0);
|
||||||
dy += poll_coord2;
|
int poll_coord2 = coord_buffer.get(1);
|
||||||
x += poll_coord1;
|
/* The wheel is always relative */
|
||||||
y += poll_coord2;
|
int poll_dwheel = coord_buffer.get(2);
|
||||||
absolute_x += poll_coord1;
|
|
||||||
absolute_y += poll_coord2;
|
|
||||||
} else {
|
|
||||||
dx = poll_coord1 - absolute_x;
|
|
||||||
dy = poll_coord2 - absolute_y;
|
|
||||||
absolute_x = x = poll_coord1;
|
|
||||||
absolute_y = y = poll_coord2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(clipMouseCoordinatesToWindow) {
|
if (isGrabbed()) {
|
||||||
x = Math.min(Display.getWidth() - 1, Math.max(0, x));
|
dx += poll_coord1;
|
||||||
y = Math.min(Display.getHeight() - 1, Math.max(0, y));
|
dy += poll_coord2;
|
||||||
}
|
x += poll_coord1;
|
||||||
|
y += poll_coord2;
|
||||||
dwheel += poll_dwheel;
|
absolute_x += poll_coord1;
|
||||||
read();
|
absolute_y += poll_coord2;
|
||||||
|
} else {
|
||||||
|
dx = poll_coord1 - absolute_x;
|
||||||
|
dy = poll_coord2 - absolute_y;
|
||||||
|
absolute_x = x = poll_coord1;
|
||||||
|
absolute_y = y = poll_coord2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clipMouseCoordinatesToWindow) {
|
||||||
|
x = Math.min(Display.getWidth() - 1, Math.max(0, x));
|
||||||
|
y = Math.min(Display.getHeight() - 1, Math.max(0, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
dwheel += poll_dwheel;
|
||||||
|
read();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void read() {
|
private static void read() {
|
||||||
|
@ -395,12 +384,11 @@ public class Mouse {
|
||||||
* @return true if the specified button is down
|
* @return true if the specified button is down
|
||||||
*/
|
*/
|
||||||
public static boolean isButtonDown(int button) {
|
public static boolean isButtonDown(int button) {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (!created) throw new IllegalStateException("Mouse must be created before you can poll the button state");
|
||||||
if (!created) throw new IllegalStateException("Mouse must be created before you can poll the button state");
|
if (button >= buttonCount || button < 0) {
|
||||||
if (button >= buttonCount || button < 0)
|
return false;
|
||||||
return false;
|
} else {
|
||||||
else
|
return buttons.get(button) == 1;
|
||||||
return buttons.get(button) == 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,11 +398,10 @@ public class Mouse {
|
||||||
* @return a String with the button's human readable name in it or null if the button is unnamed
|
* @return a String with the button's human readable name in it or null if the button is unnamed
|
||||||
*/
|
*/
|
||||||
public static String getButtonName(int button) {
|
public static String getButtonName(int button) {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (button >= buttonName.length || button < 0) {
|
||||||
if (button >= buttonName.length || button < 0)
|
return null;
|
||||||
return null;
|
} else {
|
||||||
else
|
return buttonName[button];
|
||||||
return buttonName[button];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,12 +410,11 @@ public class Mouse {
|
||||||
* @param buttonName The button name
|
* @param buttonName The button name
|
||||||
*/
|
*/
|
||||||
public static int getButtonIndex(String buttonName) {
|
public static int getButtonIndex(String buttonName) {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
Integer ret = buttonMap.get(buttonName);
|
||||||
Integer ret = buttonMap.get(buttonName);
|
if (ret == null) {
|
||||||
if (ret == null)
|
return -1;
|
||||||
return -1;
|
} else {
|
||||||
else
|
return ret;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +428,6 @@ public class Mouse {
|
||||||
* @return true if a mouse event was read, false otherwise
|
* @return true if a mouse event was read, false otherwise
|
||||||
*/
|
*/
|
||||||
public static boolean next() {
|
public static boolean next() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
|
||||||
if (!created) throw new IllegalStateException("Mouse must be created before you can read events");
|
if (!created) throw new IllegalStateException("Mouse must be created before you can read events");
|
||||||
if (readBuffer.hasRemaining()) {
|
if (readBuffer.hasRemaining()) {
|
||||||
eventButton = readBuffer.get();
|
eventButton = readBuffer.get();
|
||||||
|
@ -464,25 +449,23 @@ public class Mouse {
|
||||||
last_event_raw_x = new_event_x;
|
last_event_raw_x = new_event_x;
|
||||||
last_event_raw_y = new_event_y;
|
last_event_raw_y = new_event_y;
|
||||||
}
|
}
|
||||||
if(clipMouseCoordinatesToWindow) {
|
if (clipMouseCoordinatesToWindow) {
|
||||||
event_x = Math.min(Display.getWidth() - 1, Math.max(0, event_x));
|
event_x = Math.min(Display.getWidth() - 1, Math.max(0, event_x));
|
||||||
event_y = Math.min(Display.getHeight() - 1, Math.max(0, event_y));
|
event_y = Math.min(Display.getHeight() - 1, Math.max(0, event_y));
|
||||||
}
|
}
|
||||||
event_dwheel = readBuffer.getInt();
|
event_dwheel = readBuffer.getInt();
|
||||||
event_nanos = readBuffer.getLong();
|
event_nanos = readBuffer.getLong();
|
||||||
return true;
|
return true;
|
||||||
} else
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current events button. Returns -1 if no button state was changed
|
* @return Current events button. Returns -1 if no button state was changed
|
||||||
*/
|
*/
|
||||||
public static int getEventButton() {
|
public static int getEventButton() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return eventButton;
|
||||||
return eventButton;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -490,54 +473,42 @@ public class Mouse {
|
||||||
* @return Current events button state.
|
* @return Current events button state.
|
||||||
*/
|
*/
|
||||||
public static boolean getEventButtonState() {
|
public static boolean getEventButtonState() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return eventState;
|
||||||
return eventState;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current events delta x.
|
* @return Current events delta x.
|
||||||
*/
|
*/
|
||||||
public static int getEventDX() {
|
public static int getEventDX() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return event_dx;
|
||||||
return event_dx;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current events delta y.
|
* @return Current events delta y.
|
||||||
*/
|
*/
|
||||||
public static int getEventDY() {
|
public static int getEventDY() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return event_dy;
|
||||||
return event_dy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current events absolute x.
|
* @return Current events absolute x.
|
||||||
*/
|
*/
|
||||||
public static int getEventX() {
|
public static int getEventX() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return event_x;
|
||||||
return event_x;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current events absolute y.
|
* @return Current events absolute y.
|
||||||
*/
|
*/
|
||||||
public static int getEventY() {
|
public static int getEventY() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return event_y;
|
||||||
return event_y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current events delta z
|
* @return Current events delta z
|
||||||
*/
|
*/
|
||||||
public static int getEventDWheel() {
|
public static int getEventDWheel() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return event_dwheel;
|
||||||
return event_dwheel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -549,9 +520,7 @@ public class Mouse {
|
||||||
* @return The time in nanoseconds of the current event
|
* @return The time in nanoseconds of the current event
|
||||||
*/
|
*/
|
||||||
public static long getEventNanoseconds() {
|
public static long getEventNanoseconds() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return event_nanos;
|
||||||
return event_nanos;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -561,9 +530,7 @@ public class Mouse {
|
||||||
* @return Absolute x axis position of mouse
|
* @return Absolute x axis position of mouse
|
||||||
*/
|
*/
|
||||||
public static int getX() {
|
public static int getX() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return x;
|
||||||
return x;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -573,69 +540,55 @@ public class Mouse {
|
||||||
* @return Absolute y axis position of mouse
|
* @return Absolute y axis position of mouse
|
||||||
*/
|
*/
|
||||||
public static int getY() {
|
public static int getY() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return y;
|
||||||
return y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Movement on the x axis since last time getDX() was called.
|
* @return Movement on the x axis since last time getDX() was called.
|
||||||
*/
|
*/
|
||||||
public static int getDX() {
|
public static int getDX() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
int result = dx;
|
||||||
int result = dx;
|
dx = 0;
|
||||||
dx = 0;
|
return result;
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Movement on the y axis since last time getDY() was called.
|
* @return Movement on the y axis since last time getDY() was called.
|
||||||
*/
|
*/
|
||||||
public static int getDY() {
|
public static int getDY() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
int result = dy;
|
||||||
int result = dy;
|
dy = 0;
|
||||||
dy = 0;
|
return result;
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Movement of the wheel since last time getDWheel() was called
|
* @return Movement of the wheel since last time getDWheel() was called
|
||||||
*/
|
*/
|
||||||
public static int getDWheel() {
|
public static int getDWheel() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
int result = dwheel;
|
||||||
int result = dwheel;
|
dwheel = 0;
|
||||||
dwheel = 0;
|
return result;
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Number of buttons on this mouse
|
* @return Number of buttons on this mouse
|
||||||
*/
|
*/
|
||||||
public static int getButtonCount() {
|
public static int getButtonCount() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return buttonCount;
|
||||||
return buttonCount;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether or not this mouse has wheel support
|
* @return Whether or not this mouse has wheel support
|
||||||
*/
|
*/
|
||||||
public static boolean hasWheel() {
|
public static boolean hasWheel() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return hasWheel;
|
||||||
return hasWheel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return whether or not the mouse has grabbed the cursor
|
* @return whether or not the mouse has grabbed the cursor
|
||||||
*/
|
*/
|
||||||
public static boolean isGrabbed() {
|
public static boolean isGrabbed() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
return isGrabbed;
|
||||||
return isGrabbed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -647,31 +600,31 @@ public class Mouse {
|
||||||
* @param grab whether the mouse should be grabbed
|
* @param grab whether the mouse should be grabbed
|
||||||
*/
|
*/
|
||||||
public static void setGrabbed(boolean grab) {
|
public static void setGrabbed(boolean grab) {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
boolean grabbed = isGrabbed;
|
||||||
boolean grabbed = isGrabbed;
|
if (grabbed == grab) return;
|
||||||
isGrabbed = grab;
|
|
||||||
if (isCreated()) {
|
|
||||||
if (grab && !grabbed) {
|
|
||||||
// store location mouse was grabbed
|
|
||||||
grab_x = x;
|
|
||||||
grab_y = y;
|
|
||||||
}
|
|
||||||
else if (!grab && grabbed) {
|
|
||||||
// move mouse back to location it was grabbed before ungrabbing
|
|
||||||
if ((Cursor.getCapabilities() & Cursor.CURSOR_ONE_BIT_TRANSPARENCY) != 0)
|
|
||||||
implementation.setCursorPosition(grab_x, grab_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
implementation.grabMouse(grab);
|
isGrabbed = grab;
|
||||||
// Get latest values from native side
|
|
||||||
poll();
|
if (!isCreated()) return;
|
||||||
event_x = x;
|
|
||||||
event_y = y;
|
if (grab && !grabbed) {
|
||||||
last_event_raw_x = x;
|
// store location mouse was grabbed
|
||||||
last_event_raw_y = y;
|
grab_x = x;
|
||||||
resetMouse();
|
grab_y = y;
|
||||||
}
|
} else if (!grab && grabbed) {
|
||||||
|
// move mouse back to location it was grabbed before ungrabbing
|
||||||
|
if ((Cursor.getCapabilities() & Cursor.CURSOR_ONE_BIT_TRANSPARENCY) != 0)
|
||||||
|
implementation.setCursorPosition(grab_x, grab_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
implementation.grabMouse(grab);
|
||||||
|
// Get latest values from native side
|
||||||
|
poll();
|
||||||
|
event_x = x;
|
||||||
|
event_y = y;
|
||||||
|
last_event_raw_x = x;
|
||||||
|
last_event_raw_y = y;
|
||||||
|
resetMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -680,25 +633,23 @@ public class Mouse {
|
||||||
* shouldn't be called otherwise
|
* shouldn't be called otherwise
|
||||||
*/
|
*/
|
||||||
public static void updateCursor() {
|
public static void updateCursor() {
|
||||||
synchronized (OpenGLPackageAccess.global_lock) {
|
if (emulateCursorAnimation && currentCursor != null && currentCursor.hasTimedOut() && Mouse.isInsideWindow()) {
|
||||||
if (emulateCursorAnimation && currentCursor != null && currentCursor.hasTimedOut() && Mouse.isInsideWindow()) {
|
currentCursor.nextCursor();
|
||||||
currentCursor.nextCursor();
|
try {
|
||||||
try {
|
setNativeCursor(currentCursor);
|
||||||
setNativeCursor(currentCursor);
|
} catch (LWJGLException e) {
|
||||||
} catch (LWJGLException e) {
|
if (LWJGLUtil.DEBUG) e.printStackTrace();
|
||||||
if (LWJGLUtil.DEBUG) e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves whether or not the mouse cursor is within the bounds of the window.
|
* Retrieves whether or not the mouse cursor is within the bounds of the window.
|
||||||
* If the mouse cursor was moved outside the display during a drag, then the result of calling
|
* If the mouse cursor was moved outside the display during a drag, then the result of calling
|
||||||
* this method will be true until the button is released.
|
* this method will be true until the button is released.
|
||||||
* @return true if mouse is inside display, false otherwise.
|
* @return true if mouse is inside display, false otherwise.
|
||||||
*/
|
*/
|
||||||
public static boolean isInsideWindow() {
|
public static boolean isInsideWindow() {
|
||||||
return implementation.isInsideWindow();
|
return implementation.isInsideWindow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,7 @@ public final class ALC10 {
|
||||||
boolean result = nalcCloseDevice(getDevice(device));
|
boolean result = nalcCloseDevice(getDevice(device));
|
||||||
synchronized (devices) {
|
synchronized (devices) {
|
||||||
device.setInvalid();
|
device.setInvalid();
|
||||||
devices.remove(new Long(device.device));
|
devices.remove(Long.valueOf(device.device));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ public final class ALC11 {
|
||||||
boolean result = nalcCaptureCloseDevice(ALC10.getDevice(device));
|
boolean result = nalcCaptureCloseDevice(ALC10.getDevice(device));
|
||||||
synchronized (ALC10.devices) {
|
synchronized (ALC10.devices) {
|
||||||
device.setInvalid();
|
device.setInvalid();
|
||||||
ALC10.devices.remove(new Long(device.device));
|
ALC10.devices.remove(Long.valueOf(device.device));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ import java.nio.FloatBuffer;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
import static org.lwjgl.LWJGLUtil.getPrivilegedBoolean;
|
import static org.lwjgl.LWJGLUtil.getPrivilegedBoolean;
|
||||||
|
@ -127,9 +128,7 @@ public final class Display {
|
||||||
|
|
||||||
private static final ComponentListener component_listener = new ComponentAdapter() {
|
private static final ComponentListener component_listener = new ComponentAdapter() {
|
||||||
public void componentResized(ComponentEvent e) {
|
public void componentResized(ComponentEvent e) {
|
||||||
synchronized ( GlobalLock.lock ) {
|
parent_resized = true;
|
||||||
parent_resized = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -186,24 +185,28 @@ public final class Display {
|
||||||
* @return an array of all display modes the system reckons it can handle.
|
* @return an array of all display modes the system reckons it can handle.
|
||||||
*/
|
*/
|
||||||
public static DisplayMode[] getAvailableDisplayModes() throws LWJGLException {
|
public static DisplayMode[] getAvailableDisplayModes() throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
DisplayMode[] unfilteredModes = display_impl.getAvailableDisplayModes();
|
||||||
DisplayMode[] unfilteredModes = display_impl.getAvailableDisplayModes();
|
|
||||||
|
|
||||||
if ( unfilteredModes == null ) {
|
if (unfilteredModes == null) {
|
||||||
return new DisplayMode[0];
|
return new DisplayMode[0];
|
||||||
}
|
|
||||||
|
|
||||||
// We'll use a HashSet to filter out the duplicated modes
|
|
||||||
HashSet<DisplayMode> modes = new HashSet<DisplayMode>(unfilteredModes.length);
|
|
||||||
|
|
||||||
modes.addAll(Arrays.asList(unfilteredModes));
|
|
||||||
DisplayMode[] filteredModes = new DisplayMode[modes.size()];
|
|
||||||
modes.toArray(filteredModes);
|
|
||||||
|
|
||||||
LWJGLUtil.log("Removed " + (unfilteredModes.length - filteredModes.length) + " duplicate displaymodes");
|
|
||||||
|
|
||||||
return filteredModes;
|
|
||||||
}
|
}
|
||||||
|
if (unfilteredModes.length <= 1) {
|
||||||
|
return unfilteredModes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We'll use a HashSet to filter out the duplicated modes
|
||||||
|
HashSet<DisplayMode> modes = new HashSet<>(unfilteredModes.length);
|
||||||
|
|
||||||
|
for (DisplayMode mode : unfilteredModes) {
|
||||||
|
modes.add(mode);
|
||||||
|
}
|
||||||
|
DisplayMode[] filteredModes = new DisplayMode[modes.size()];
|
||||||
|
modes.toArray(filteredModes);
|
||||||
|
|
||||||
|
int n = unfilteredModes.length - filteredModes.length;
|
||||||
|
LWJGLUtil.logger().log(() -> "Removed " + n + " duplicate displaymodes");
|
||||||
|
|
||||||
|
return filteredModes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -236,27 +239,29 @@ public final class Display {
|
||||||
* @throws LWJGLException if the display mode could not be set
|
* @throws LWJGLException if the display mode could not be set
|
||||||
*/
|
*/
|
||||||
public static void setDisplayMode(DisplayMode mode) throws LWJGLException {
|
public static void setDisplayMode(DisplayMode mode) throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
Objects.requireNonNull(mode, "mode must be non-null");
|
||||||
if ( mode == null )
|
|
||||||
throw new NullPointerException("mode must be non-null");
|
if (mode == current_mode) return;
|
||||||
boolean was_fullscreen = isFullscreen();
|
|
||||||
current_mode = mode;
|
boolean was_fullscreen = isFullscreen();
|
||||||
if ( !isCreated() || parent != null )
|
current_mode = mode;
|
||||||
return;
|
|
||||||
destroyWindow();
|
if (!isCreated() || parent != null) return;
|
||||||
// If mode is not fullscreen capable, make sure we are in windowed mode
|
|
||||||
try {
|
destroyWindow();
|
||||||
if ( was_fullscreen && !isFullscreen() )
|
|
||||||
display_impl.resetDisplayMode();
|
// If mode is not fullscreen capable, make sure we are in windowed mode
|
||||||
else if ( isFullscreen() )
|
try {
|
||||||
switchDisplayMode();
|
if ( was_fullscreen && !isFullscreen() )
|
||||||
createWindow();
|
|
||||||
makeCurrentAndSetSwapInterval();
|
|
||||||
} catch (LWJGLException e) {
|
|
||||||
drawable.destroy();
|
|
||||||
display_impl.resetDisplayMode();
|
display_impl.resetDisplayMode();
|
||||||
throw e;
|
else if ( isFullscreen() )
|
||||||
}
|
switchDisplayMode();
|
||||||
|
createWindow();
|
||||||
|
makeCurrentAndSetSwapInterval();
|
||||||
|
} catch (LWJGLException e) {
|
||||||
|
drawable.destroy();
|
||||||
|
display_impl.resetDisplayMode();
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,37 +375,35 @@ public final class Display {
|
||||||
* @param contrast The contrast, larger than 0.0.
|
* @param contrast The contrast, larger than 0.0.
|
||||||
*/
|
*/
|
||||||
public static void setDisplayConfiguration(float gamma, float brightness, float contrast) throws LWJGLException {
|
public static void setDisplayConfiguration(float gamma, float brightness, float contrast) throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if ( !isCreated() ) {
|
||||||
if ( !isCreated() ) {
|
throw new LWJGLException("Display not yet created.");
|
||||||
throw new LWJGLException("Display not yet created.");
|
|
||||||
}
|
|
||||||
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 = display_impl.getGammaRampLength();
|
|
||||||
if ( rampSize == 0 ) {
|
|
||||||
throw new LWJGLException("Display configuration not supported");
|
|
||||||
}
|
|
||||||
FloatBuffer gammaRamp = BufferUtils.createFloatBuffer(rampSize);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
display_impl.setGammaRamp(gammaRamp);
|
|
||||||
LWJGLUtil.log("Gamma set, gamma = " + gamma + ", brightness = " + brightness + ", contrast = " + contrast);
|
|
||||||
}
|
}
|
||||||
|
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 = display_impl.getGammaRampLength();
|
||||||
|
if ( rampSize == 0 ) {
|
||||||
|
throw new LWJGLException("Display configuration not supported");
|
||||||
|
}
|
||||||
|
FloatBuffer gammaRamp = BufferUtils.createFloatBuffer(rampSize);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
display_impl.setGammaRamp(gammaRamp);
|
||||||
|
LWJGLUtil.log("Gamma set, gamma = " + gamma + ", brightness = " + brightness + ", contrast = " + contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -434,25 +437,23 @@ public final class Display {
|
||||||
* the Dispaly will inherit the size of the parent, disregarding the currently set display mode.<p>
|
* the Dispaly will inherit the size of the parent, disregarding the currently set display mode.<p>
|
||||||
*/
|
*/
|
||||||
public static void setParent(Canvas parent) throws LWJGLException {
|
public static void setParent(Canvas parent) throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if ( Display.parent != parent ) {
|
||||||
if ( Display.parent != parent ) {
|
Display.parent = parent;
|
||||||
Display.parent = parent;
|
if ( !isCreated() )
|
||||||
if ( !isCreated() )
|
return;
|
||||||
return;
|
destroyWindow();
|
||||||
destroyWindow();
|
try {
|
||||||
try {
|
if ( isFullscreen() ) {
|
||||||
if ( isFullscreen() ) {
|
switchDisplayMode();
|
||||||
switchDisplayMode();
|
} else {
|
||||||
} else {
|
|
||||||
display_impl.resetDisplayMode();
|
|
||||||
}
|
|
||||||
createWindow();
|
|
||||||
makeCurrentAndSetSwapInterval();
|
|
||||||
} catch (LWJGLException e) {
|
|
||||||
drawable.destroy();
|
|
||||||
display_impl.resetDisplayMode();
|
display_impl.resetDisplayMode();
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
|
createWindow();
|
||||||
|
makeCurrentAndSetSwapInterval();
|
||||||
|
} catch (LWJGLException e) {
|
||||||
|
drawable.destroy();
|
||||||
|
display_impl.resetDisplayMode();
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,30 +490,27 @@ public final class Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setDisplayModeAndFullscreenInternal(boolean fullscreen, DisplayMode mode) throws LWJGLException {
|
private static void setDisplayModeAndFullscreenInternal(boolean fullscreen, DisplayMode mode) throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if ( mode == null )
|
||||||
if ( mode == null )
|
throw new NullPointerException("mode must be non-null");
|
||||||
throw new NullPointerException("mode must be non-null");
|
DisplayMode old_mode = current_mode;
|
||||||
DisplayMode old_mode = current_mode;
|
current_mode = mode;
|
||||||
current_mode = mode;
|
boolean was_fullscreen = isFullscreen();
|
||||||
boolean was_fullscreen = isFullscreen();
|
Display.fullscreen = fullscreen;
|
||||||
Display.fullscreen = fullscreen;
|
if (was_fullscreen != isFullscreen() || !mode.equals(old_mode)) {
|
||||||
if ( was_fullscreen != isFullscreen() || !mode.equals(old_mode) ) {
|
if (!isCreated()) return;
|
||||||
if ( !isCreated() )
|
destroyWindow();
|
||||||
return;
|
try {
|
||||||
destroyWindow();
|
if ( isFullscreen() ) {
|
||||||
try {
|
switchDisplayMode();
|
||||||
if ( isFullscreen() ) {
|
} else {
|
||||||
switchDisplayMode();
|
|
||||||
} else {
|
|
||||||
display_impl.resetDisplayMode();
|
|
||||||
}
|
|
||||||
createWindow();
|
|
||||||
makeCurrentAndSetSwapInterval();
|
|
||||||
} catch (LWJGLException e) {
|
|
||||||
drawable.destroy();
|
|
||||||
display_impl.resetDisplayMode();
|
display_impl.resetDisplayMode();
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
|
createWindow();
|
||||||
|
makeCurrentAndSetSwapInterval();
|
||||||
|
} catch (LWJGLException e) {
|
||||||
|
drawable.destroy();
|
||||||
|
display_impl.resetDisplayMode();
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -528,41 +526,37 @@ public final class Display {
|
||||||
* @param newTitle The new window title
|
* @param newTitle The new window title
|
||||||
*/
|
*/
|
||||||
public static void setTitle(String newTitle) {
|
public static void setTitle(String newTitle) {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if ( newTitle == null ) {
|
||||||
if ( newTitle == null ) {
|
newTitle = "";
|
||||||
newTitle = "";
|
}
|
||||||
}
|
title = newTitle;
|
||||||
title = newTitle;
|
if (isCreated()) {
|
||||||
if ( isCreated() )
|
display_impl.setTitle(title);
|
||||||
display_impl.setTitle(title);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return true if the user or operating system has asked the window to close */
|
/** @return true if the user or operating system has asked the window to close */
|
||||||
public static boolean isCloseRequested() {
|
public static boolean isCloseRequested() {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if (!isCreated()) {
|
||||||
if ( !isCreated() )
|
throw new IllegalStateException("Cannot determine close requested state of uncreated window");
|
||||||
throw new IllegalStateException("Cannot determine close requested state of uncreated window");
|
|
||||||
return display_impl.isCloseRequested();
|
|
||||||
}
|
}
|
||||||
|
return display_impl.isCloseRequested();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return true if the window is visible, false if not */
|
/** @return true if the window is visible, false if not */
|
||||||
public static boolean isVisible() {
|
public static boolean isVisible() {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if (!isCreated()) {
|
||||||
if ( !isCreated() )
|
throw new IllegalStateException("Cannot determine minimized state of uncreated window");
|
||||||
throw new IllegalStateException("Cannot determine minimized state of uncreated window");
|
|
||||||
return display_impl.isVisible();
|
|
||||||
}
|
}
|
||||||
|
return display_impl.isVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return true if window is active, that is, the foreground display of the operating system. */
|
/** @return true if window is active, that is, the foreground display of the operating system. */
|
||||||
public static boolean isActive() {
|
public static boolean isActive() {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if (!isCreated()) {
|
||||||
if ( !isCreated() )
|
throw new IllegalStateException("Cannot determine focused state of uncreated window");
|
||||||
throw new IllegalStateException("Cannot determine focused state of uncreated window");
|
|
||||||
return display_impl.isActive();
|
|
||||||
}
|
}
|
||||||
|
return display_impl.isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -576,11 +570,10 @@ public final class Display {
|
||||||
* and needs to repaint itself
|
* and needs to repaint itself
|
||||||
*/
|
*/
|
||||||
public static boolean isDirty() {
|
public static boolean isDirty() {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if (!isCreated()) {
|
||||||
if ( !isCreated() )
|
throw new IllegalStateException("Cannot determine dirty state of uncreated window");
|
||||||
throw new IllegalStateException("Cannot determine dirty state of uncreated window");
|
|
||||||
return display_impl.isDirty();
|
|
||||||
}
|
}
|
||||||
|
return display_impl.isDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -589,12 +582,11 @@ public final class Display {
|
||||||
* this method if update() is called periodically.
|
* this method if update() is called periodically.
|
||||||
*/
|
*/
|
||||||
public static void processMessages() {
|
public static void processMessages() {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if (!isCreated()) {
|
||||||
if ( !isCreated() )
|
throw new IllegalStateException("Display not created");
|
||||||
throw new IllegalStateException("Display not created");
|
|
||||||
|
|
||||||
display_impl.update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
display_impl.update();
|
||||||
pollDevices();
|
pollDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,14 +597,15 @@ public final class Display {
|
||||||
* @throws OpenGLException if an OpenGL error has occured since the last call to glGetError()
|
* @throws OpenGLException if an OpenGL error has occured since the last call to glGetError()
|
||||||
*/
|
*/
|
||||||
public static void swapBuffers() throws LWJGLException {
|
public static void swapBuffers() throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if (!isCreated()) {
|
||||||
if ( !isCreated() )
|
throw new IllegalStateException("Display not created");
|
||||||
throw new IllegalStateException("Display not created");
|
|
||||||
|
|
||||||
if ( LWJGLUtil.DEBUG )
|
|
||||||
drawable.checkGLError();
|
|
||||||
drawable.swapBuffers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LWJGLUtil.DEBUG) {
|
||||||
|
drawable.checkGLError();
|
||||||
|
}
|
||||||
|
|
||||||
|
drawable.swapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -632,49 +625,49 @@ public final class Display {
|
||||||
* @param processMessages Poll input devices if true
|
* @param processMessages Poll input devices if true
|
||||||
*/
|
*/
|
||||||
public static void update(boolean processMessages) {
|
public static void update(boolean processMessages) {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if (!isCreated()) {
|
||||||
if ( !isCreated() )
|
throw new IllegalStateException("Display not created");
|
||||||
throw new IllegalStateException("Display not created");
|
}
|
||||||
|
|
||||||
// We paint only when the window is visible or dirty
|
// We paint only when the window is visible or dirty
|
||||||
if ( display_impl.isVisible() || display_impl.isDirty() ) {
|
if (display_impl.isVisible() || display_impl.isDirty()) {
|
||||||
try {
|
try {
|
||||||
swapBuffers();
|
swapBuffers();
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
window_resized = !isFullscreen() && parent == null && display_impl.wasResized();
|
window_resized = !isFullscreen() && parent == null && display_impl.wasResized();
|
||||||
|
|
||||||
if ( window_resized ) {
|
if (window_resized) {
|
||||||
width = display_impl.getWidth();
|
width = display_impl.getWidth();
|
||||||
height = display_impl.getHeight();
|
height = display_impl.getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( parent_resized ) {
|
if (parent_resized) {
|
||||||
reshape();
|
reshape();
|
||||||
parent_resized = false;
|
parent_resized = false;
|
||||||
window_resized = true;
|
window_resized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( processMessages )
|
if (processMessages) {
|
||||||
processMessages();
|
processMessages();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pollDevices() {
|
static void pollDevices() {
|
||||||
// Poll the input devices while we're here
|
// Poll the input devices while we're here
|
||||||
if ( Mouse.isCreated() ) {
|
if (Mouse.isCreated()) {
|
||||||
Mouse.poll();
|
Mouse.poll();
|
||||||
Mouse.updateCursor();
|
Mouse.updateCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Keyboard.isCreated() ) {
|
if (Keyboard.isCreated()) {
|
||||||
Keyboard.poll();
|
Keyboard.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Controllers.isCreated() ) {
|
if (Controllers.isCreated()) {
|
||||||
Controllers.poll();
|
Controllers.poll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -703,20 +696,16 @@ public final class Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void removeShutdownHook() {
|
private static void removeShutdownHook() {
|
||||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||||
public Object run() {
|
Runtime.getRuntime().removeShutdownHook(shutdown_hook);
|
||||||
Runtime.getRuntime().removeShutdownHook(shutdown_hook);
|
return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void registerShutdownHook() {
|
private static void registerShutdownHook() {
|
||||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||||
public Object run() {
|
Runtime.getRuntime().addShutdownHook(shutdown_hook);
|
||||||
Runtime.getRuntime().addShutdownHook(shutdown_hook);
|
return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,9 +738,7 @@ public final class Display {
|
||||||
* @throws LWJGLException
|
* @throws LWJGLException
|
||||||
*/
|
*/
|
||||||
public static void create(PixelFormat pixel_format) throws LWJGLException {
|
public static void create(PixelFormat pixel_format) throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
create(pixel_format, null, (ContextAttribs)null);
|
||||||
create(pixel_format, null, (ContextAttribs)null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -769,9 +756,7 @@ public final class Display {
|
||||||
* @throws LWJGLException
|
* @throws LWJGLException
|
||||||
*/
|
*/
|
||||||
public static void create(PixelFormat pixel_format, Drawable shared_drawable) throws LWJGLException {
|
public static void create(PixelFormat pixel_format, Drawable shared_drawable) throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
create(pixel_format, shared_drawable, (ContextAttribs)null);
|
||||||
create(pixel_format, shared_drawable, (ContextAttribs)null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -789,9 +774,7 @@ public final class Display {
|
||||||
* @throws LWJGLException
|
* @throws LWJGLException
|
||||||
*/
|
*/
|
||||||
public static void create(PixelFormat pixel_format, ContextAttribs attribs) throws LWJGLException {
|
public static void create(PixelFormat pixel_format, ContextAttribs attribs) throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
create(pixel_format, null, attribs);
|
||||||
create(pixel_format, null, attribs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -881,9 +864,7 @@ public final class Display {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static void create(PixelFormatLWJGL pixel_format) throws LWJGLException {
|
public static void create(PixelFormatLWJGL pixel_format) throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
create(pixel_format, null, null);
|
||||||
create(pixel_format, null, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -901,9 +882,7 @@ public final class Display {
|
||||||
* @throws LWJGLException
|
* @throws LWJGLException
|
||||||
*/
|
*/
|
||||||
public static void create(PixelFormatLWJGL pixel_format, Drawable shared_drawable) throws LWJGLException {
|
public static void create(PixelFormatLWJGL pixel_format, Drawable shared_drawable) throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
create(pixel_format, shared_drawable, null);
|
||||||
create(pixel_format, shared_drawable, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -921,9 +900,7 @@ public final class Display {
|
||||||
* @throws LWJGLException
|
* @throws LWJGLException
|
||||||
*/
|
*/
|
||||||
public static void create(PixelFormatLWJGL pixel_format, org.lwjgl.opengles.ContextAttribs attribs) throws LWJGLException {
|
public static void create(PixelFormatLWJGL pixel_format, org.lwjgl.opengles.ContextAttribs attribs) throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
create(pixel_format, null, attribs);
|
||||||
create(pixel_format, null, attribs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1038,15 +1015,15 @@ public final class Display {
|
||||||
|
|
||||||
private static void initControls() {
|
private static void initControls() {
|
||||||
// Automatically create mouse, keyboard and controller
|
// Automatically create mouse, keyboard and controller
|
||||||
if ( !getPrivilegedBoolean("org.lwjgl.opengl.Display.noinput") ) {
|
if (!getPrivilegedBoolean("org.lwjgl.opengl.Display.noinput")) {
|
||||||
if ( !Mouse.isCreated() && !getPrivilegedBoolean("org.lwjgl.opengl.Display.nomouse") ) {
|
if (!Mouse.isCreated() && !getPrivilegedBoolean("org.lwjgl.opengl.Display.nomouse")) {
|
||||||
try {
|
try {
|
||||||
Mouse.create();
|
Mouse.create();
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
LWJGLUtil.logger().log("Failed to create Mouse", e);
|
LWJGLUtil.logger().log("Failed to create Mouse", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( !Keyboard.isCreated() && !getPrivilegedBoolean("org.lwjgl.opengl.Display.nokeyboard") ) {
|
if (!Keyboard.isCreated() && !getPrivilegedBoolean("org.lwjgl.opengl.Display.nokeyboard")) {
|
||||||
try {
|
try {
|
||||||
Keyboard.create();
|
Keyboard.create();
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
|
@ -1091,11 +1068,11 @@ public final class Display {
|
||||||
* @param value The swap interval in frames, 0 to disable
|
* @param value The swap interval in frames, 0 to disable
|
||||||
*/
|
*/
|
||||||
public static void setSwapInterval(int value) throws LWJGLException {
|
public static void setSwapInterval(int value) throws LWJGLException {
|
||||||
synchronized ( GlobalLock.lock ) {
|
if (value != swap_interval) {
|
||||||
swap_interval = value;
|
swap_interval = value;
|
||||||
if ( isCreated() )
|
if (isCreated()) {
|
||||||
drawable.setSwapInterval(swap_interval);
|
drawable.setSwapInterval(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,15 +1097,13 @@ public final class Display {
|
||||||
* @param new_y The new window location on the y axis
|
* @param new_y The new window location on the y axis
|
||||||
*/
|
*/
|
||||||
public static void setLocation(int new_x, int new_y) {
|
public static void setLocation(int new_x, int new_y) {
|
||||||
synchronized ( GlobalLock.lock ) {
|
// cache position
|
||||||
// cache position
|
x = new_x;
|
||||||
x = new_x;
|
y = new_y;
|
||||||
y = new_y;
|
|
||||||
|
|
||||||
// offset if already created
|
// offset if already created
|
||||||
if ( isCreated() && !isFullscreen() ) {
|
if ( isCreated() && !isFullscreen() ) {
|
||||||
reshape();
|
reshape();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,25 +1150,23 @@ public final class Display {
|
||||||
* @return number of icons used, or 0 if display hasn't been created
|
* @return number of icons used, or 0 if display hasn't been created
|
||||||
*/
|
*/
|
||||||
public static int setIcon(ByteBuffer[] icons) {
|
public static int setIcon(ByteBuffer[] icons) {
|
||||||
synchronized ( GlobalLock.lock ) {
|
// make deep copy so we dont rely on the supplied buffers later on
|
||||||
// make deep copy so we dont rely on the supplied buffers later on
|
// don't recache!
|
||||||
// don't recache!
|
if (cached_icons != icons) {
|
||||||
if ( cached_icons != icons ) {
|
cached_icons = new ByteBuffer[icons.length];
|
||||||
cached_icons = new ByteBuffer[icons.length];
|
for ( int i = 0; i < icons.length; i++ ) {
|
||||||
for ( int i = 0; i < icons.length; i++ ) {
|
cached_icons[i] = BufferUtils.createByteBuffer(icons[i].capacity());
|
||||||
cached_icons[i] = BufferUtils.createByteBuffer(icons[i].capacity());
|
int old_position = icons[i].position();
|
||||||
int old_position = icons[i].position();
|
cached_icons[i].put(icons[i]);
|
||||||
cached_icons[i].put(icons[i]);
|
icons[i].position(old_position);
|
||||||
icons[i].position(old_position);
|
cached_icons[i].flip();
|
||||||
cached_icons[i].flip();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( Display.isCreated() && parent == null ) {
|
if (Display.isCreated() && parent == null) {
|
||||||
return display_impl.setIcon(cached_icons);
|
return display_impl.setIcon(cached_icons);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1204,9 +1177,11 @@ public final class Display {
|
||||||
* false to disable resizing on the Display window.
|
* false to disable resizing on the Display window.
|
||||||
*/
|
*/
|
||||||
public static void setResizable(boolean resizable) {
|
public static void setResizable(boolean resizable) {
|
||||||
window_resizable = resizable;
|
if (window_resizable != resizable) {
|
||||||
if ( isCreated() ) {
|
window_resizable = resizable;
|
||||||
display_impl.setResizable(resizable);
|
if (isCreated()) {
|
||||||
|
display_impl.setResizable(resizable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1235,7 +1210,6 @@ public final class Display {
|
||||||
* the parent will be returned.
|
* the parent will be returned.
|
||||||
*/
|
*/
|
||||||
public static int getX() {
|
public static int getX() {
|
||||||
|
|
||||||
if (Display.isFullscreen()) {
|
if (Display.isFullscreen()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1255,7 +1229,6 @@ public final class Display {
|
||||||
* the parent will be returned.
|
* the parent will be returned.
|
||||||
*/
|
*/
|
||||||
public static int getY() {
|
public static int getY() {
|
||||||
|
|
||||||
if (Display.isFullscreen()) {
|
if (Display.isFullscreen()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1277,7 +1250,6 @@ public final class Display {
|
||||||
* This value will be updated after a call to Display.update().
|
* This value will be updated after a call to Display.update().
|
||||||
*/
|
*/
|
||||||
public static int getWidth() {
|
public static int getWidth() {
|
||||||
|
|
||||||
if (Display.isFullscreen()) {
|
if (Display.isFullscreen()) {
|
||||||
return Display.getDisplayMode().getWidth();
|
return Display.getDisplayMode().getWidth();
|
||||||
}
|
}
|
||||||
|
@ -1299,7 +1271,6 @@ public final class Display {
|
||||||
* This value will be updated after a call to Display.update().
|
* This value will be updated after a call to Display.update().
|
||||||
*/
|
*/
|
||||||
public static int getHeight() {
|
public static int getHeight() {
|
||||||
|
|
||||||
if (Display.isFullscreen()) {
|
if (Display.isFullscreen()) {
|
||||||
return Display.getDisplayMode().getHeight();
|
return Display.getDisplayMode().getHeight();
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,10 +81,10 @@ public final class BackgroundLoadTest {
|
||||||
|
|
||||||
Util.checkGLError();
|
Util.checkGLError();
|
||||||
|
|
||||||
while ( run ) {
|
while (run) {
|
||||||
if ( !Display.isVisible() )
|
if (!Display.isVisible()) {
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
else {
|
} else {
|
||||||
handleIO();
|
handleIO();
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
@ -100,8 +100,9 @@ public final class BackgroundLoadTest {
|
||||||
|
|
||||||
Display.update();
|
Display.update();
|
||||||
|
|
||||||
if ( Display.isCloseRequested() )
|
if (Display.isCloseRequested()) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
|
@ -115,7 +116,8 @@ public final class BackgroundLoadTest {
|
||||||
DisplayMode displayMode = null;
|
DisplayMode displayMode = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DisplayMode[] modes = Display.getAvailableDisplayModes();
|
displayMode = Display.getDisplayMode();
|
||||||
|
/*DisplayMode[] modes = Display.getAvailableDisplayModes();
|
||||||
|
|
||||||
displayMode = chooseMode(modes, 1024, 768);
|
displayMode = chooseMode(modes, 1024, 768);
|
||||||
if ( displayMode == null )
|
if ( displayMode == null )
|
||||||
|
@ -126,7 +128,7 @@ public final class BackgroundLoadTest {
|
||||||
kill("Failed to set an appropriate display mode.");
|
kill("Failed to set an appropriate display mode.");
|
||||||
|
|
||||||
System.out.println("Setting display mode to: " + displayMode);
|
System.out.println("Setting display mode to: " + displayMode);
|
||||||
Display.setDisplayMode(displayMode);
|
Display.setDisplayMode(displayMode);*/
|
||||||
Display.setTitle("Background Loading Test");
|
Display.setTitle("Background Loading Test");
|
||||||
Display.create(new PixelFormat(8, 24, 0));
|
Display.create(new PixelFormat(8, 24, 0));
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
|
@ -189,18 +191,10 @@ public final class BackgroundLoadTest {
|
||||||
|
|
||||||
sphere = new Sphere();
|
sphere = new Sphere();
|
||||||
|
|
||||||
if ( "PB".equalsIgnoreCase(args[0]) ) {
|
if ("PB".equalsIgnoreCase(args[0])) {
|
||||||
backgroundLoader = new BackgroundLoader() {
|
backgroundLoader = new BackgroundLoader(() -> new Pbuffer(2, 2, new PixelFormat(8, 24, 0), Display.getDrawable()));
|
||||||
Drawable getDrawable() throws LWJGLException {
|
} else if ("SD".equalsIgnoreCase(args[0])) {
|
||||||
return new Pbuffer(2, 2, new PixelFormat(8, 24, 0), Display.getDrawable());
|
backgroundLoader = new BackgroundLoader(() -> new SharedDrawable(Display.getDrawable()));
|
||||||
}
|
|
||||||
};
|
|
||||||
} else if ( "SD".equalsIgnoreCase(args[0]) ) {
|
|
||||||
backgroundLoader = new BackgroundLoader() {
|
|
||||||
Drawable getDrawable() throws LWJGLException {
|
|
||||||
return new SharedDrawable(Display.getDrawable());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
argsError();
|
argsError();
|
||||||
}
|
}
|
||||||
|
@ -227,7 +221,7 @@ public final class BackgroundLoadTest {
|
||||||
glColor3f(1.0f, 1.0f, 1.0f);
|
glColor3f(1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
int texID = backgroundLoader.getTexID();
|
int texID = backgroundLoader.getTexID();
|
||||||
if ( texID == 0 ) {
|
if (texID == 0) {
|
||||||
sphere.setTextureFlag(false);
|
sphere.setTextureFlag(false);
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
} else {
|
} else {
|
||||||
|
@ -238,7 +232,8 @@ public final class BackgroundLoadTest {
|
||||||
|
|
||||||
sphere.draw(1.0f, 32, 32);
|
sphere.draw(1.0f, 32, 32);
|
||||||
|
|
||||||
if ( texID != 0 ) { // Unbind so we can update from the background thread.
|
if (texID != 0) {
|
||||||
|
// Unbind so we can update from the background thread.
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
}
|
}
|
||||||
|
@ -247,9 +242,9 @@ public final class BackgroundLoadTest {
|
||||||
private static DisplayMode chooseMode(DisplayMode[] modes, int width, int height) {
|
private static DisplayMode chooseMode(DisplayMode[] modes, int width, int height) {
|
||||||
DisplayMode bestMode = null;
|
DisplayMode bestMode = null;
|
||||||
|
|
||||||
for ( DisplayMode mode : modes ) {
|
for (DisplayMode mode : modes) {
|
||||||
if ( mode.getWidth() == width && mode.getHeight() == height && mode.getFrequency() <= 85 ) {
|
if (mode.getWidth() == width && mode.getHeight() == height && mode.getFrequency() <= 85) {
|
||||||
if ( bestMode == null || (mode.getBitsPerPixel() >= bestMode.getBitsPerPixel() && mode.getFrequency() > bestMode.getFrequency()) )
|
if (bestMode == null || (mode.getBitsPerPixel() >= bestMode.getBitsPerPixel() && mode.getFrequency() > bestMode.getFrequency()) )
|
||||||
bestMode = mode;
|
bestMode = mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,7 +253,9 @@ public final class BackgroundLoadTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void cleanup() {
|
private static void cleanup() {
|
||||||
backgroundLoader.cleanup();
|
if (backgroundLoader != null) {
|
||||||
|
backgroundLoader.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
Thread.yield(); // Let background thread finish.
|
Thread.yield(); // Let background thread finish.
|
||||||
|
|
||||||
|
|
|
@ -46,55 +46,57 @@ import org.lwjgl.util.Color;
|
||||||
import org.lwjgl.util.ReadableColor;
|
import org.lwjgl.util.ReadableColor;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL11.*;
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
import static org.lwjgl.opengl.GL32.*;
|
import static org.lwjgl.opengl.GL32.*;
|
||||||
|
|
||||||
abstract class BackgroundLoader {
|
final class BackgroundLoader {
|
||||||
|
|
||||||
private static final int WIDTH = 32;
|
private static final int WIDTH = 64;
|
||||||
private static final int HEIGHT = 32;
|
private static final int HEIGHT = 64;
|
||||||
|
|
||||||
// CPU synchronization
|
|
||||||
private final ReentrantLock lock = new ReentrantLock();
|
|
||||||
// GPU synchronization
|
// GPU synchronization
|
||||||
private GLSync fence;
|
private GLSync fence;
|
||||||
|
|
||||||
private Drawable drawable;
|
private final DrawableSupplier drawableSupplier;
|
||||||
|
|
||||||
|
private Drawable drawable;
|
||||||
|
private int texID;
|
||||||
private boolean running;
|
private boolean running;
|
||||||
|
|
||||||
private ByteBuffer texture;
|
protected BackgroundLoader(DrawableSupplier drawableSupplier) {
|
||||||
private int texID;
|
this.drawableSupplier = drawableSupplier;
|
||||||
|
this.running = true;
|
||||||
protected BackgroundLoader() {
|
|
||||||
running = true;
|
|
||||||
texture = BufferUtils.createByteBuffer(WIDTH * HEIGHT * 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract Drawable getDrawable() throws LWJGLException;
|
|
||||||
|
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void uploadTexture(int texID, ByteBuffer texture, boolean useFences) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texID);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, texture);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
if (useFences) {
|
||||||
|
//while (fence != null) {}
|
||||||
|
fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
|
} else {
|
||||||
|
// Best we can do without fences. This will force rendering on the main thread to happen after we upload the texture.
|
||||||
|
glFlush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void start() throws LWJGLException {
|
void start() throws LWJGLException {
|
||||||
// The shared context must be created on the main thread.
|
this.drawable = this.drawableSupplier.get();
|
||||||
drawable = getDrawable();
|
|
||||||
|
|
||||||
new Thread(new Runnable() {
|
new Thread(() -> {
|
||||||
public void run() {
|
|
||||||
System.out.println("-- Background Thread started --");
|
System.out.println("-- Background Thread started --");
|
||||||
|
|
||||||
System.out.println("** Sleeping, no texture created yet **");
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(2000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Make the shared context current in the worker thread
|
// Make the shared context current in the worker thread
|
||||||
drawable.makeCurrent();
|
drawable.makeCurrent();
|
||||||
|
@ -104,69 +106,57 @@ abstract class BackgroundLoader {
|
||||||
|
|
||||||
System.out.println("** Drawable created **");
|
System.out.println("** Drawable created **");
|
||||||
|
|
||||||
// Create a "dummy" texture while we wait for texture IO
|
|
||||||
createCheckerTexture(Color.RED, Color.WHITE, 2);
|
|
||||||
|
|
||||||
lock.lock();
|
|
||||||
|
|
||||||
texID = glGenTextures();
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texID);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, texture);
|
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
// OpenGL commands from different contexts may be executed in any order. So we need a way to synchronize
|
// OpenGL commands from different contexts may be executed in any order. So we need a way to synchronize
|
||||||
final boolean useFences = GLContext.getCapabilities().OpenGL32;
|
final boolean useFences = GLContext.getCapabilities().OpenGL32;
|
||||||
|
System.out.println("Using fences: " + useFences);
|
||||||
|
|
||||||
if ( useFences )
|
System.out.println("** Sleeping, no texture created yet **");
|
||||||
fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
|
||||||
else
|
|
||||||
glFlush(); // Best we can do without fences. This will force rendering on the main thread to happen after we upload the texture.
|
|
||||||
|
|
||||||
lock.unlock();
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer texture = BufferUtils.createByteBuffer(WIDTH * HEIGHT * 3);
|
||||||
|
|
||||||
|
// Create a "dummy" texture while we wait for texture IO
|
||||||
|
createCheckerTexture(texture, Color.RED, Color.WHITE, 2);
|
||||||
|
|
||||||
|
texID = glGenTextures();
|
||||||
|
uploadTexture(texID, texture, useFences);
|
||||||
|
|
||||||
System.out.println("** Dummy texture created **");
|
System.out.println("** Dummy texture created **");
|
||||||
|
|
||||||
|
long avgGenTime = 0L;
|
||||||
|
long avgUploadTime = 0L;
|
||||||
|
long lastUploadTime = 0L;
|
||||||
|
|
||||||
long lastTextureCreated = System.currentTimeMillis(); // Delay first texture creation
|
long lastTextureCreated = System.currentTimeMillis(); // Delay first texture creation
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while ( running ) {
|
while ( running ) {
|
||||||
long time = System.currentTimeMillis();
|
/*long time = System.currentTimeMillis();
|
||||||
if ( time - lastTextureCreated < 5000 ) { // Update the texture every 5 seconds
|
if (time - lastTextureCreated < 2) { // Update the texture every 5 seconds
|
||||||
try {
|
|
||||||
Thread.sleep(200);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Create the "true" texture
|
// Create the "true" texture
|
||||||
if ( count % 2 == 0 )
|
long start = System.nanoTime();
|
||||||
createGradientTexture(Color.RED, Color.BLUE);
|
if ( count % 2 == 0 ) {
|
||||||
else
|
createGradientTexture(texture, Color.RED, Color.BLUE);
|
||||||
createGradientTexture(Color.GREEN, Color.YELLOW);
|
} else {
|
||||||
|
createGradientTexture(texture, Color.GREEN, Color.YELLOW);
|
||||||
|
}
|
||||||
|
long elapsed = System.nanoTime() - start;
|
||||||
|
avgGenTime = (avgGenTime + elapsed) >> 1;
|
||||||
|
|
||||||
lock.lock();
|
start = System.nanoTime();
|
||||||
|
uploadTexture(texID, texture, useFences);
|
||||||
|
lastUploadTime = System.nanoTime() - start;
|
||||||
|
avgUploadTime = (avgUploadTime + lastUploadTime) >> 1;
|
||||||
|
//System.out.println("Uploaded texture in " + elapsed + " ns.");
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texID);
|
//System.out.println("** Created new gradient texture **");
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, texture);
|
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
if ( useFences )
|
|
||||||
fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
|
||||||
else
|
|
||||||
glFlush();
|
|
||||||
|
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
System.out.println("** Created new gradient texture **");
|
|
||||||
|
|
||||||
lastTextureCreated = System.currentTimeMillis();
|
lastTextureCreated = System.currentTimeMillis();
|
||||||
count++;
|
count++;
|
||||||
|
@ -175,24 +165,26 @@ abstract class BackgroundLoader {
|
||||||
drawable.destroy();
|
drawable.destroy();
|
||||||
|
|
||||||
System.out.println("-- Background Thread finished --");
|
System.out.println("-- Background Thread finished --");
|
||||||
}
|
System.out.println("Generated textures in " + avgGenTime + " ns on average.");
|
||||||
|
System.out.println("Uploaded textures in " + avgUploadTime + " ns on average.");
|
||||||
|
System.out.println("Most recently uploaded textures in " + lastUploadTime + " ns.");
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getTexID() {
|
public final int getTexID() {
|
||||||
lock.lock();
|
//lock.lock();
|
||||||
try {
|
try {
|
||||||
if ( fence != null ) {
|
if (fence != null) {
|
||||||
glWaitSync(fence, 0, GL_TIMEOUT_IGNORED);
|
glWaitSync(fence, 0, GL_TIMEOUT_IGNORED);
|
||||||
fence = null;
|
fence = null;
|
||||||
}
|
}
|
||||||
return texID;
|
return texID;
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
//lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createCheckerTexture(final ReadableColor a, final ReadableColor b, final int size) {
|
private static void createCheckerTexture(ByteBuffer texture, final ReadableColor a, final ReadableColor b, final int size) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for ( int y = 0; y < HEIGHT; y++ ) {
|
for ( int y = 0; y < HEIGHT; y++ ) {
|
||||||
for ( int x = 0; x < WIDTH; x++ ) {
|
for ( int x = 0; x < WIDTH; x++ ) {
|
||||||
|
@ -205,7 +197,7 @@ abstract class BackgroundLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createGradientTexture(final ReadableColor a, final ReadableColor b) {
|
private static void createGradientTexture(ByteBuffer texture, final ReadableColor a, final ReadableColor b) {
|
||||||
float l = 0.0f;
|
float l = 0.0f;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for ( int y = 0; y < HEIGHT; y++ ) {
|
for ( int y = 0; y < HEIGHT; y++ ) {
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package org.lwjgl.test.opengl.multithread;
|
||||||
|
|
||||||
|
import org.lwjgl.LWJGLException;
|
||||||
|
import org.lwjgl.opengl.Drawable;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
interface DrawableSupplier {
|
||||||
|
Drawable get() throws LWJGLException;
|
||||||
|
}
|
Loading…
Reference in New Issue