diff --git a/build.xml b/build.xml index d625767..857af24 100644 --- a/build.xml +++ b/build.xml @@ -124,7 +124,6 @@ - @@ -133,7 +132,6 @@ - @@ -253,6 +251,7 @@ + diff --git a/platform_build/build-definitions.xml b/platform_build/build-definitions.xml index bca0657..c977dc4 100644 --- a/platform_build/build-definitions.xml +++ b/platform_build/build-definitions.xml @@ -12,7 +12,7 @@ - + diff --git a/platform_build/build-generator.xml b/platform_build/build-generator.xml index 8e9a596..b9bac2d 100644 --- a/platform_build/build-generator.xml +++ b/platform_build/build-generator.xml @@ -13,8 +13,10 @@ + + @@ -37,7 +39,7 @@ - + @@ -55,7 +57,7 @@ - + diff --git a/platform_build/build-webstart.xml b/platform_build/build-webstart.xml index 875254c..96aec03 100644 --- a/platform_build/build-webstart.xml +++ b/platform_build/build-webstart.xml @@ -7,7 +7,7 @@ - + @@ -25,6 +25,8 @@ + + @@ -36,18 +38,62 @@ - + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + - + + + + + @@ -57,5 +103,6 @@ + diff --git a/platform_build/build-webstart.xml.bak b/platform_build/build-webstart.xml.bak deleted file mode 100644 index 1ad0af3..0000000 --- a/platform_build/build-webstart.xml.bak +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/java/org/lwjgl/BufferChecks.java b/src/java/org/lwjgl/BufferChecks.java index e982e8b..b35a4a4 100644 --- a/src/java/org/lwjgl/BufferChecks.java +++ b/src/java/org/lwjgl/BufferChecks.java @@ -48,8 +48,8 @@ *

* @author cix_foo * @author elias_naur - * @version $Revision: 3279 $ - * $Id: BufferChecks.java 3279 2010-03-11 21:06:49Z spasi $ + * @version $Revision: 3334 $ + * $Id: BufferChecks.java 3334 2010-04-22 23:21:48Z spasi $ */ public class BufferChecks { /** Static methods only! */ @@ -60,7 +60,7 @@ * Helper methods to ensure a function pointer is not-null (0) */ public static void checkFunctionAddress(long pointer) { - if (pointer == 0) { + if (LWJGLUtil.CHECKS && pointer == 0) { throw new IllegalStateException("Function is not supported"); } } @@ -69,20 +69,22 @@ * Helper methods to ensure a ByteBuffer is null-terminated */ public static void checkNullTerminated(ByteBuffer buf) { - if (buf.get(buf.limit() - 1) != 0) { + if ( LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0) { throw new IllegalArgumentException("Missing null termination"); } } public static void checkNullTerminated(ByteBuffer buf, int count) { - int nullFound = 0; - for ( int i = buf.position(); i < buf.limit(); i++ ) { - if ( buf.get(i) == 0 ) - nullFound++; - } - - if ( nullFound < count ) - throw new IllegalArgumentException("Missing null termination"); + if ( LWJGLUtil.CHECKS ) { + int nullFound = 0; + for ( int i = buf.position(); i < buf.limit(); i++ ) { + if ( buf.get(i) == 0 ) + nullFound++; + } + + if ( nullFound < count ) + throw new IllegalArgumentException("Missing null termination"); + } } /** Helper methods to ensure an IntBuffer is null-terminated */ @@ -93,7 +95,7 @@ } public static void checkNotNull(Object o) { - if (o == null) + if ( LWJGLUtil.CHECKS && o == null) throw new IllegalArgumentException("Null argument"); } @@ -101,37 +103,37 @@ * Helper methods to ensure a buffer is direct (and, implicitly, non-null). */ public static void checkDirect(ByteBuffer buf) { - if (!buf.isDirect()) { + if ( LWJGLUtil.CHECKS && !buf.isDirect()) { throw new IllegalArgumentException("ByteBuffer is not direct"); } } public static void checkDirect(ShortBuffer buf) { - if (!buf.isDirect()) { + if ( LWJGLUtil.CHECKS && !buf.isDirect()) { throw new IllegalArgumentException("ShortBuffer is not direct"); } } public static void checkDirect(IntBuffer buf) { - if (!buf.isDirect()) { + if ( LWJGLUtil.CHECKS && !buf.isDirect()) { throw new IllegalArgumentException("IntBuffer is not direct"); } } public static void checkDirect(LongBuffer buf) { - if (!buf.isDirect()) { + if ( LWJGLUtil.CHECKS && !buf.isDirect()) { throw new IllegalArgumentException("LongBuffer is not direct"); } } public static void checkDirect(FloatBuffer buf) { - if (!buf.isDirect()) { + if ( LWJGLUtil.CHECKS && !buf.isDirect()) { throw new IllegalArgumentException("FloatBuffer is not direct"); } } public static void checkDirect(DoubleBuffer buf) { - if (!buf.isDirect()) { + if ( LWJGLUtil.CHECKS && !buf.isDirect()) { throw new IllegalArgumentException("DoubleBuffer is not direct"); } } @@ -154,38 +156,50 @@ * @throws IllegalArgumentException */ public static void checkBufferSize(Buffer buf, int size) { - if (buf.remaining() < size) { + if ( LWJGLUtil.CHECKS && buf.remaining() < size) { throwBufferSizeException(buf, size); } } public static void checkBuffer(ByteBuffer buf, int size) { - checkBufferSize(buf, size); - checkDirect(buf); + if ( LWJGLUtil.CHECKS ) { + checkBufferSize(buf, size); + checkDirect(buf); + } } public static void checkBuffer(ShortBuffer buf, int size) { - checkBufferSize(buf, size); - checkDirect(buf); + if ( LWJGLUtil.CHECKS ) { + checkBufferSize(buf, size); + checkDirect(buf); + } } public static void checkBuffer(IntBuffer buf, int size) { - checkBufferSize(buf, size); - checkDirect(buf); + if ( LWJGLUtil.CHECKS ) { + checkBufferSize(buf, size); + checkDirect(buf); + } } public static void checkBuffer(LongBuffer buf, int size) { - checkBufferSize(buf, size); - checkDirect(buf); + if ( LWJGLUtil.CHECKS ) { + checkBufferSize(buf, size); + checkDirect(buf); + } } public static void checkBuffer(FloatBuffer buf, int size) { - checkBufferSize(buf, size); - checkDirect(buf); + if ( LWJGLUtil.CHECKS ) { + checkBufferSize(buf, size); + checkDirect(buf); + } } public static void checkBuffer(DoubleBuffer buf, int size) { - checkBufferSize(buf, size); - checkDirect(buf); + if ( LWJGLUtil.CHECKS ) { + checkBufferSize(buf, size); + checkDirect(buf); + } } } diff --git a/src/java/org/lwjgl/LWJGLUtil.java b/src/java/org/lwjgl/LWJGLUtil.java index 86ab4f6..ad4e82f 100644 --- a/src/java/org/lwjgl/LWJGLUtil.java +++ b/src/java/org/lwjgl/LWJGLUtil.java @@ -49,8 +49,8 @@ *

* * @author Brian Matzon - * @version $Revision: 2983 $ - * $Id: LWJGLUtil.java 2983 2008-04-07 18:36:09Z matzon $ + * @version $Revision: 3334 $ + * $Id: LWJGLUtil.java 3334 2010-04-22 23:21:48Z spasi $ */ public class LWJGLUtil { public static final int PLATFORM_LINUX = 1; @@ -266,7 +266,9 @@ /** Debug flag. */ public static final boolean DEBUG = getPrivilegedBoolean("org.lwjgl.util.Debug"); - + + public static final boolean CHECKS = !getPrivilegedBoolean("org.lwjgl.util.NoChecks"); + static { LWJGLIcon16x16.flip(); LWJGLIcon32x32.flip(); diff --git a/src/java/org/lwjgl/Sys.java b/src/java/org/lwjgl/Sys.java index c1e0344..7b2c528 100644 --- a/src/java/org/lwjgl/Sys.java +++ b/src/java/org/lwjgl/Sys.java @@ -46,15 +46,15 @@ * System class (named Sys so as not to conflict with java.lang.System) *

* @author cix_foo - * @version $Revision: 3328 $ - * $Id: Sys.java 3328 2010-04-15 18:03:54Z matzon $ + * @version $Revision: 3353 $ + * $Id: Sys.java 3353 2010-05-24 22:39:06Z matzon $ */ public final class Sys { /** The native library name */ private static final String JNI_LIBRARY_NAME = "lwjgl"; /** Current version of library */ - private static final String VERSION = "2.4.2"; + private static final String VERSION = "2.5"; /** The implementation instance to delegate platform specific behavior to */ private final static SysImplementation implementation; diff --git a/src/java/org/lwjgl/input/Mouse.java b/src/java/org/lwjgl/input/Mouse.java index 028d8e7..06cabc8 100644 --- a/src/java/org/lwjgl/input/Mouse.java +++ b/src/java/org/lwjgl/input/Mouse.java @@ -59,8 +59,8 @@ * @author cix_foo * @author elias_naur * @author Brian Matzon - * @version $Revision: 3297 $ - * $Id: Mouse.java 3297 2010-03-27 16:04:30Z kappa1 $ + * @version $Revision: 3337 $ + * $Id: Mouse.java 3337 2010-04-29 17:37:18Z matzon $ */ public class Mouse { /** Internal use - event size in bytes */ @@ -467,7 +467,7 @@ } /** - * @return Current events delta x. Only valid when the mouse is grabbed. + * @return Current events delta x. */ public static int getEventDX() { synchronized (OpenGLPackageAccess.global_lock) { @@ -476,7 +476,7 @@ } /** - * @return Current events delta y. Only valid when the mouse is grabbed. + * @return Current events delta y. */ public static int getEventDY() { synchronized (OpenGLPackageAccess.global_lock) { @@ -485,7 +485,7 @@ } /** - * @return Current events absolute x. Only valid when the mouse is not grabbed. + * @return Current events absolute x. */ public static int getEventX() { synchronized (OpenGLPackageAccess.global_lock) { @@ -494,7 +494,7 @@ } /** - * @return Current events absolute y. Only valid when the mouse is not grabbed. + * @return Current events absolute y. */ public static int getEventY() { synchronized (OpenGLPackageAccess.global_lock) { @@ -550,7 +550,7 @@ } /** - * @return Movement on the x axis since last time getDX() was called. Only valid when the mouse is grabbed. + * @return Movement on the x axis since last time getDX() was called. */ public static int getDX() { synchronized (OpenGLPackageAccess.global_lock) { @@ -561,7 +561,7 @@ } /** - * @return Movement on the y axis since last time getDY() was called. Only valid when the mouse is grabbed. + * @return Movement on the y axis since last time getDY() was called. */ public static int getDY() { synchronized (OpenGLPackageAccess.global_lock) { diff --git a/src/java/org/lwjgl/openal/AL.java b/src/java/org/lwjgl/openal/AL.java index a689880..9c9bc70 100644 --- a/src/java/org/lwjgl/openal/AL.java +++ b/src/java/org/lwjgl/openal/AL.java @@ -42,8 +42,8 @@ *

* * @author Brian Matzon - * @version $Revision: 3182 $ - * $Id: AL.java 3182 2009-03-17 21:36:18Z matzon $ + * @version $Revision: 3348 $ + * $Id: AL.java 3348 2010-05-24 21:54:37Z matzon $ */ public final class AL { /** ALCdevice instance. */ @@ -160,8 +160,9 @@ if(openDevice) { device = ALC10.alcOpenDevice(deviceArguments); - if (device == null) + if (device == null) { throw new LWJGLException("Could not open ALC device"); + } if (contextFrequency == -1) { context = ALC10.alcCreateContext(device, null); @@ -177,7 +178,18 @@ throw e; } - ALC11.initialize(); + ALC11.initialize(); + + // Load EFX10 native stubs if ALC_EXT_EFX is supported. + // Is there any situation where the current device supports ALC_EXT_EFX and one + // later created by the user does not? + // Do we have to call resetNativeStubs(EFX10.class); somewhere? Not done for AL11 + // either. + // This can either be here or in ALC11, since ALC_EXT_EFX indirectly requires AL 1.1 + // for functions like alSource3i. + if (ALC10.alcIsExtensionPresent(device, EFX10.ALC_EXT_EFX_NAME)){ + EFX10.initNativeStubs(); + } } /** @@ -205,8 +217,10 @@ device = null; } resetNativeStubs(AL10.class); + resetNativeStubs(AL11.class); resetNativeStubs(ALC10.class); resetNativeStubs(ALC11.class); + resetNativeStubs(EFX10.class); if (created) nDestroy(); diff --git a/src/java/org/lwjgl/openal/ALC11.java b/src/java/org/lwjgl/openal/ALC11.java index b470440..1f7f88d 100644 --- a/src/java/org/lwjgl/openal/ALC11.java +++ b/src/java/org/lwjgl/openal/ALC11.java @@ -58,6 +58,9 @@ public static final int ALC_CAPTURE_DEVICE_SPECIFIER = 0x310; public static final int ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER = 0x311; public static final int ALC_CAPTURE_SAMPLES = 0x312; + + public static final int ALC_MONO_SOURCES = 0x1010; + public static final int ALC_STEREO_SOURCES = 0x1011; /** * The alcCaptureOpenDevice function allows the application to connect to a capture diff --git a/src/java/org/lwjgl/openal/EFXUtil.java b/src/java/org/lwjgl/openal/EFXUtil.java new file mode 100644 index 0000000..780e3f6 --- /dev/null +++ b/src/java/org/lwjgl/openal/EFXUtil.java @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2002-2010 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.openal; + +/** + * Utility class for the OpenAL extension ALC_EXT_EFX. Provides functions to check for the extension + * and support of various effects and filters. + *

+ * Currently supports ALC_EXT_EFX version 1.0 effects and filters. + * + * @author Ciardhubh + * @version $Revision$ + * $Id$ + */ +public final class EFXUtil { + + /** Constant for testSupportGeneric to check an effect. */ + private static final int EFFECT = 1111; + /** Constant for testSupportGeneric to check a filter. */ + private static final int FILTER = 2222; + + /** Utility class, hidden contructor. */ + private EFXUtil() { + } + + /** + * Checks if OpenAL implementation is loaded and supports ALC_EXT_EFX. + * + * @return True if ALC_EXT_EFX is supported, false if not. + * @throws OpenALException If OpenAL has not been created yet. + */ + public static boolean isEfxSupported() { + if (!AL.isCreated()) { + throw new OpenALException("OpenAL has not been created."); + } + return ALC10.alcIsExtensionPresent(AL.getDevice(), EFX10.ALC_EXT_EFX_NAME); + } + + /** + * Tests OpenAL to see whether the given effect type is supported. This is done by creating an + * effect of the given type. If creation succeeds the effect is supported. + * + * @param effectType Type of effect whose support is to be tested, e.g. AL_EFFECT_REVERB. + * @return True if it is supported, false if not. + * @throws OpenALException If the request fails due to an AL_OUT_OF_MEMORY error or OpenAL has + * not been created yet. + * @throws IllegalArgumentException effectType is not a valid effect type. + */ + public static boolean isEffectSupported(final int effectType) { + // Make sure type is a real effect. + switch (effectType) { + case EFX10.AL_EFFECT_NULL: + case EFX10.AL_EFFECT_EAXREVERB: + case EFX10.AL_EFFECT_REVERB: + case EFX10.AL_EFFECT_CHORUS: + case EFX10.AL_EFFECT_DISTORTION: + case EFX10.AL_EFFECT_ECHO: + case EFX10.AL_EFFECT_FLANGER: + case EFX10.AL_EFFECT_FREQUENCY_SHIFTER: + case EFX10.AL_EFFECT_VOCAL_MORPHER: + case EFX10.AL_EFFECT_PITCH_SHIFTER: + case EFX10.AL_EFFECT_RING_MODULATOR: + case EFX10.AL_EFFECT_AUTOWAH: + case EFX10.AL_EFFECT_COMPRESSOR: + case EFX10.AL_EFFECT_EQUALIZER: + break; + default: + throw new IllegalArgumentException("Unknown or invalid effect type: " + effectType); + } + + return testSupportGeneric(EFFECT, effectType); + } + + /** + * Tests OpenAL to see whether the given filter type is supported. This is done by creating a + * filter of the given type. If creation succeeds the filter is supported. + * + * @param filterType Type of filter whose support is to be tested, e.g. AL_FILTER_LOWPASS. + * @return True if it is supported, false if not. + * @throws OpenALException If the request fails due to an AL_OUT_OF_MEMORY error or OpenAL has + * not been created yet. + * @throws IllegalArgumentException filterType is not a valid filter type. + */ + public static boolean isFilterSupported(final int filterType) { + // Make sure type is a real filter. + switch (filterType) { + case EFX10.AL_FILTER_NULL: + case EFX10.AL_FILTER_LOWPASS: + case EFX10.AL_FILTER_HIGHPASS: + case EFX10.AL_FILTER_BANDPASS: + break; + default: + throw new IllegalArgumentException("Unknown or invalid filter type: " + filterType); + } + + return testSupportGeneric(FILTER, filterType); + } + + /** + * Generic test function to see if an EFX object supports a given kind of type. Works for + * effects and filters. + * + * @param objectType Type of object to test. Must be either EFXUtil.EFFECT or EFXUtil.FILTER. + * @param typeValue OpenAL type the object should be tested for support, e.g. AL_FILTER_LOWPASS + * or AL_EFFECT_REVERB. + * @return True if object supports typeValue, false else. + */ + private static boolean testSupportGeneric(final int objectType, final int typeValue) { + // Check for supported objectType. + switch (objectType) { + case EFFECT: + case FILTER: + break; + default: + throw new IllegalArgumentException("Invalid objectType: " + objectType); + } + + boolean supported = false; + if (isEfxSupported()) { + + // Try to create object in order to check AL's response. + AL10.alGetError(); + int genError; + int testObject = 0; + try { + switch (objectType) { // Create object based on type + case EFFECT: + testObject = EFX10.alGenEffects(); + break; + case FILTER: + testObject = EFX10.alGenFilters(); + break; + default: + throw new IllegalArgumentException("Invalid objectType: " + objectType); + } + genError = AL10.alGetError(); + } catch (final OpenALException debugBuildException) { + // Hack because OpenALException hides the original error code (short of parsing the + // error message String which would break if it gets changed). + if (debugBuildException.getMessage().contains("AL_OUT_OF_MEMORY")) { + genError = AL10.AL_OUT_OF_MEMORY; + } else { + genError = AL10.AL_INVALID_OPERATION; + } + } + + if (genError == AL10.AL_NO_ERROR) { + // Successfully created, now try to set type. + AL10.alGetError(); + int setError; + try { + switch (objectType) { // Set based on object type + case EFFECT: + EFX10.alEffecti(testObject, EFX10.AL_EFFECT_TYPE, typeValue); + break; + case FILTER: + EFX10.alFilteri(testObject, EFX10.AL_FILTER_TYPE, typeValue); + break; + default: + throw new IllegalArgumentException("Invalid objectType: " + objectType); + } + setError = AL10.alGetError(); + } catch (final OpenALException debugBuildException) { + // Hack because OpenALException hides the original error code (short of parsing + // the error message String which would break when it gets changed). + setError = AL10.AL_INVALID_VALUE; + } + + if (setError == AL10.AL_NO_ERROR) { + supported = true; + } + + // Cleanup + try { + switch (objectType) { // Set based on object type + case EFFECT: + EFX10.alDeleteEffects(testObject); + break; + case FILTER: + EFX10.alDeleteFilters(testObject); + break; + default: + throw new IllegalArgumentException("Invalid objectType: " + objectType); + } + } catch (final OpenALException debugBuildException) { + // Don't care about cleanup errors. + } + + } else if (genError == AL10.AL_OUT_OF_MEMORY) { + throw new OpenALException(genError); + } + } + + return supported; + } +} diff --git a/src/java/org/lwjgl/opengl/AMDDebugOutputCallback.java b/src/java/org/lwjgl/opengl/AMDDebugOutputCallback.java new file mode 100644 index 0000000..0038161 --- /dev/null +++ b/src/java/org/lwjgl/opengl/AMDDebugOutputCallback.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * Instances of this class are needed to use the callback functionality of the AMD_debug_output extension. + * A debug context must be current before creating instances of this class. Users of this class may provide + * implementations of the {@code Handler} interface to receive notifications. The same {@code Handler} + * instance may be used by different contexts but it is not recommended. Handler notifications are synchronized. + * + * @author Spasi + */ +public final class AMDDebugOutputCallback implements PointerWrapper { + + /** Severity levels. */ + private static final int GL_DEBUG_SEVERITY_HIGH_AMD = 0x9146, + GL_DEBUG_SEVERITY_MEDIUM_AMD = 0x9147, + GL_DEBUG_SEVERITY_LOW_AMD = 0x9148; + + /** Categories */ + private static final int GL_DEBUG_CATEGORY_API_ERROR_AMD = 0x9149, + GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD = 0x914A, + GL_DEBUG_CATEGORY_DEPRECATION_AMD = 0x914B, + GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD = 0x914C, + GL_DEBUG_CATEGORY_PERFORMANCE_AMD = 0x914D, + GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD = 0x914E, + GL_DEBUG_CATEGORY_APPLICATION_AMD = 0x914F, + GL_DEBUG_CATEGORY_OTHER_AMD = 0x9150; + + private final long pointer; + + /** + * Creates a AMDDebugOutputCallback with a default callback handler. + * The default handler will simply print the message on System.err. + */ + public AMDDebugOutputCallback() { + this(new Handler() { + public void handleMessage(final int id, final int category, final int severity, final String message) { + System.err.println("[LWJGL] AMD_debug_output message"); + System.err.println("\tID: " + id); + + String description; + switch ( category ) { + case GL_DEBUG_CATEGORY_API_ERROR_AMD: + description = "API ERROR"; + break; + case GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD: + description = "WINDOW SYSTEM"; + break; + case GL_DEBUG_CATEGORY_DEPRECATION_AMD: + description = "DEPRECATION"; + break; + case GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD: + description = "UNDEFINED BEHAVIOR"; + break; + case GL_DEBUG_CATEGORY_PERFORMANCE_AMD: + description = "PERFORMANCE"; + break; + case GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD: + description = "SHADER COMPILER"; + break; + case GL_DEBUG_CATEGORY_APPLICATION_AMD: + description = "APPLICATION"; + break; + case GL_DEBUG_CATEGORY_OTHER_AMD: + description = "OTHER"; + break; + default: + description = "Unknown (" + Integer.toHexString(category) + ")"; + } + System.err.println("\tCategory: " + description); + + switch ( severity ) { + case GL_DEBUG_SEVERITY_HIGH_AMD: + description = "HIGH"; + break; + case GL_DEBUG_SEVERITY_MEDIUM_AMD: + description = "MEDIUM"; + break; + case GL_DEBUG_SEVERITY_LOW_AMD: + description = "LOW"; + break; + default: + description = "Unknown (" + Integer.toHexString(category) + ")"; + } + System.err.println("\tSeverity: " + description); + + System.err.println("\tMessage: " + message); + } + }); + } + + /** + * Creates a AMDDebugOutputCallback with the specified callback handlers. + * The handler's {@code handleMessage} method will be called whenever + * debug output is generated by the GL. + * + * @param handler the callback handler + */ + public AMDDebugOutputCallback(final Handler handler) { + try { + // We have to call registerHandler reflectively because we need this class to compile before we run the Generator. + // The registerHandler method depends on org.lwjgl.opengl.Context, if we touched that we would need to compile + // the whole library (which is not possible). + Class.forName("org.lwjgl.opengl.AMDDebugOutputUtil").getMethod("registerHandler", new Class[] { Handler.class }).invoke(null, new Object[] { handler }); + } catch (Exception e) { + throw new RuntimeException(e.getCause() != null ? e.getCause() : e); + } + this.pointer = getFunctionPointer(); + } + + public long getPointer() { + return pointer; + } + + private static native long getFunctionPointer(); + + /** Implementations of this interface can be used to receive AMD_debug_output notifications. */ + public interface Handler { + + /** + * This method will be called when an AMD_debug_output message is generated. + * + * @param id the message ID + * @param category the message category + * @param severity the message severity + * @param message the string representation of the message. + */ + void handleMessage(int id, int category, int severity, String message); + + } + +} diff --git a/src/java/org/lwjgl/opengl/AMDDebugOutputUtil.java b/src/java/org/lwjgl/opengl/AMDDebugOutputUtil.java new file mode 100644 index 0000000..1227833 --- /dev/null +++ b/src/java/org/lwjgl/opengl/AMDDebugOutputUtil.java @@ -0,0 +1,59 @@ +package org.lwjgl.opengl; + +import org.lwjgl.opengl.AMDDebugOutputCallback.Handler; + +import java.nio.ByteBuffer; +import java.util.Map; +import java.util.WeakHashMap; + +/** + * This class handles AMDDebugOutputCallback.Handler registration and notification. + * We could have put this in AMDDebugOutputCallback, but we need to compile it for + * the generator. Registration is done reflectively in the AMDDebugOutputCallback + * constructor. + * + * @author Spasi + */ +final class AMDDebugOutputUtil { + + private static final Map handlers = new WeakHashMap(); + + private AMDDebugOutputUtil() {} + + public static void registerHandler(final Handler handler) { + final Context ctx = Context.getCurrentContext(); + if ( ctx == null ) + throw new IllegalStateException("No context is current."); + + if ( !ctx.getContextAttribs().isDebug() ) + throw new IllegalStateException("The current context is not a debug context."); + + if ( !GLContext.getCapabilities().GL_AMD_debug_output ) + throw new IllegalStateException("AMD_debug_output is not supported."); + + handlers.put(ctx, handler); + } + + /** + * This method is called by native code. If finds the callback handler associated + * with the current Thread and calls its {@code handleMessage} method. + * + * @param id the message ID + * @param category the message category + * @param severity the message severity + * @param message the string representation of the message. + * @param userParam the user-specified data specified in glDebugMessageCallbackAMD. For the current implementation this is always null and we ignore it. + */ + private static void messageCallback(final int id, final int category, final int severity, final String message, final ByteBuffer userParam) { + synchronized ( GlobalLock.lock ) { + final Context ctx = Context.getCurrentContext(); + if ( ctx == null ) + return; + + final Handler handler = (Handler)handlers.get(ctx); + if ( handler != null ) + handler.handleMessage(id, category, severity, message); + } + } + +} diff --git a/src/java/org/lwjgl/opengl/APIUtils.java b/src/java/org/lwjgl/opengl/APIUtils.java index 730b801..51ded17 100644 --- a/src/java/org/lwjgl/opengl/APIUtils.java +++ b/src/java/org/lwjgl/opengl/APIUtils.java @@ -158,6 +158,7 @@ final InfiniteCharSequence infiniteSeq = getInfiniteSeq(); infiniteSeq.setString(string); encoder.encode(infiniteSeq.buffer, buffer, true); + infiniteSeq.clear(); } /** diff --git a/src/java/org/lwjgl/opengl/AWTGLCanvas.java b/src/java/org/lwjgl/opengl/AWTGLCanvas.java index 466b41b..d19f76d 100644 --- a/src/java/org/lwjgl/opengl/AWTGLCanvas.java +++ b/src/java/org/lwjgl/opengl/AWTGLCanvas.java @@ -47,10 +47,10 @@ *

* * @author $Author: spasi $ - * $Id: AWTGLCanvas.java 3116 2008-08-19 16:46:03Z spasi $ - * @version $Revision: 3116 $ + * $Id: AWTGLCanvas.java 3334 2010-04-22 23:21:48Z spasi $ + * @version $Revision: 3334 $ */ -public class AWTGLCanvas extends Canvas implements Drawable, ComponentListener, HierarchyListener { +public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListener, HierarchyListener { private static final long serialVersionUID = 1L; @@ -109,6 +109,15 @@ return context; } + /** This method should only be called internally. */ + public Context createSharedContext() throws LWJGLException { + synchronized ( SYNC_LOCK ) { + if ( context == null ) throw new IllegalStateException("Canvas not yet displayable"); + + return new Context(peer_info, context.getContextAttribs(), context); + } + } + /** Constructor using the default PixelFormat. */ public AWTGLCanvas() throws LWJGLException { this(new PixelFormat()); @@ -175,7 +184,7 @@ */ public void removeNotify() { synchronized ( SYNC_LOCK ) { - destroyContext(); + destroy(); super.removeNotify(); } } @@ -200,6 +209,26 @@ if ( context == null ) throw new IllegalStateException("Canvas not yet displayable"); Context.swapBuffers(); + } + } + + public boolean isCurrent() throws LWJGLException { + synchronized ( SYNC_LOCK ) { + if ( context == null ) throw new IllegalStateException("Canvas not yet displayable"); + + return context.isCurrent(); + } + } + + /** + * Make the canvas' context current. It is highly recommended that the context + * is only made current inside the AWT thread (for example in an overridden paintGL()). + */ + public void makeCurrent() throws LWJGLException { + synchronized ( SYNC_LOCK ) { + if ( context == null ) + throw new IllegalStateException("Canvas not yet displayable"); + context.makeCurrent(); } } @@ -212,20 +241,8 @@ } } - /** - * Make the canvas' context current. It is highly recommended that the context - * is only made current inside the AWT thread (for example in an overridden paintGL()). - */ - public void makeCurrent() throws LWJGLException { - synchronized ( SYNC_LOCK ) { - if ( context == null ) - throw new IllegalStateException("Canvas not yet displayable"); - context.makeCurrent(); - } - } - /** Destroy the OpenGL context. This happens when the component becomes undisplayable */ - private void destroyContext() { + public final void destroy() { synchronized ( SYNC_LOCK ) { try { if ( context != null ) { @@ -269,7 +286,7 @@ peer_info.lockAndGetHandle(); try { if ( context == null ) { - this.context = new Context(peer_info, attribs, drawable != null ? drawable.getContext() : null); + this.context = new Context(peer_info, attribs, drawable != null ? ((DrawableLWJGL)drawable).getContext() : null); first_run = true; } diff --git a/src/java/org/lwjgl/opengl/AbstractDrawable.java b/src/java/org/lwjgl/opengl/AbstractDrawable.java new file mode 100644 index 0000000..18778a8 --- /dev/null +++ b/src/java/org/lwjgl/opengl/AbstractDrawable.java @@ -0,0 +1,81 @@ +package org.lwjgl.opengl; + +import org.lwjgl.LWJGLException; +import org.lwjgl.LWJGLUtil; + +/** + * @author Spasi + */ +abstract class AbstractDrawable implements DrawableLWJGL { + + /** Handle to the native GL rendering context */ + protected PeerInfo peer_info; + + /** The OpenGL Context. */ + protected Context context; + + protected AbstractDrawable() { + } + + public Context getContext() { + synchronized ( GlobalLock.lock ) { + return context; + } + } + + public Context createSharedContext() throws LWJGLException { + synchronized ( GlobalLock.lock ) { + checkDestroyed(); + return new Context(peer_info, context.getContextAttribs(), context); + } + } + + public boolean isCurrent() throws LWJGLException { + synchronized ( GlobalLock.lock ) { + checkDestroyed(); + return context.isCurrent(); + } + } + + public void makeCurrent() throws LWJGLException { + synchronized ( GlobalLock.lock ) { + checkDestroyed(); + context.makeCurrent(); + } + } + + public void releaseContext() throws LWJGLException { + synchronized ( GlobalLock.lock ) { + checkDestroyed(); + if ( context.isCurrent() ) + Context.releaseCurrentContext(); + } + } + + public void destroy() { + synchronized ( GlobalLock.lock ) { + if ( context == null ) + return; + + try { + releaseContext(); + + context.forceDestroy(); + context = null; + + if ( peer_info != null ) { + peer_info.destroy(); + peer_info = null; + } + } catch (LWJGLException e) { + LWJGLUtil.log("Exception occurred while destroying Drawable: " + e); + } + } + } + + protected final void checkDestroyed() { + if ( context == null ) + throw new IllegalStateException("The Drawable has no context available."); + } + +} diff --git a/src/java/org/lwjgl/opengl/BaseReferences.java b/src/java/org/lwjgl/opengl/BaseReferences.java index 343b2c9..7058cce 100644 --- a/src/java/org/lwjgl/opengl/BaseReferences.java +++ b/src/java/org/lwjgl/opengl/BaseReferences.java @@ -32,7 +32,6 @@ package org.lwjgl.opengl; import java.nio.Buffer; -import java.nio.IntBuffer; import java.util.Arrays; class BaseReferences { @@ -49,24 +48,19 @@ int indirectBuffer; BaseReferences(ContextCapabilities caps) { - IntBuffer temp = caps.scratch_int_buffer; - int max_vertex_attribs; - if (caps.OpenGL20 || caps.GL_ARB_vertex_shader) { - GL11.glGetInteger(ARBVertexShader.GL_MAX_VERTEX_ATTRIBS_ARB, temp); - max_vertex_attribs = temp.get(0); - } else + if (caps.OpenGL20 || caps.GL_ARB_vertex_shader) + max_vertex_attribs = GL11.glGetInteger(ARBVertexShader.GL_MAX_VERTEX_ATTRIBS_ARB); + else max_vertex_attribs = 0; glVertexAttribPointer_buffer = new Buffer[max_vertex_attribs]; int max_texture_units; - if (caps.OpenGL20) { - GL11.glGetInteger(GL20.GL_MAX_TEXTURE_IMAGE_UNITS, temp); - max_texture_units = temp.get(0); - } else if (caps.OpenGL13 || caps.GL_ARB_multitexture) { - GL11.glGetInteger(GL13.GL_MAX_TEXTURE_UNITS, temp); - max_texture_units = temp.get(0); - } else + if (caps.OpenGL20) + max_texture_units = GL11.glGetInteger(GL20.GL_MAX_TEXTURE_IMAGE_UNITS); + else if (caps.OpenGL13 || caps.GL_ARB_multitexture) + max_texture_units = GL11.glGetInteger(GL13.GL_MAX_TEXTURE_UNITS); + else max_texture_units = 1; glTexCoordPointer_buffer = new Buffer[max_texture_units]; } diff --git a/src/java/org/lwjgl/opengl/Context.java b/src/java/org/lwjgl/opengl/Context.java index c07c966..1933558 100644 --- a/src/java/org/lwjgl/opengl/Context.java +++ b/src/java/org/lwjgl/opengl/Context.java @@ -46,8 +46,8 @@ * This class is thread-safe. * * @author elias_naur - * @version $Revision: 3117 $ - * $Id: Context.java 3117 2008-08-19 17:47:24Z spasi $ + * @version $Revision: 3332 $ + * $Id: Context.java 3332 2010-04-20 18:21:05Z spasi $ */ final class Context { @@ -61,7 +61,7 @@ private final ByteBuffer handle; private final PeerInfo peer_info; - private final IntBuffer attribList; + private final ContextAttribs contextAttribs; private final boolean forwardCompatible; /** Whether the context has been destroyed */ @@ -92,6 +92,10 @@ PeerInfo getPeerInfo() { return peer_info; + } + + ContextAttribs getContextAttribs() { + return contextAttribs; } static Context getCurrentContext() { @@ -109,6 +113,9 @@ GLContext.loadOpenGLLibrary(); try { this.peer_info = peer_info; + this.contextAttribs = attribs; + + IntBuffer attribList; if ( attribs != null ) { attribList = attribs.getAttribList(); forwardCompatible = attribs.isForwardCompatible(); diff --git a/src/java/org/lwjgl/opengl/ContextAttribs.java b/src/java/org/lwjgl/opengl/ContextAttribs.java index 59d951f..a056b64 100644 --- a/src/java/org/lwjgl/opengl/ContextAttribs.java +++ b/src/java/org/lwjgl/opengl/ContextAttribs.java @@ -37,16 +37,16 @@ import java.nio.IntBuffer; /** - * This class represents the context attributes passed to CreateContextAttribs of the XGL_create_context extension. + * This class represents the context attributes passed to CreateContextAttribs of the ARB_create_context and + * ARB_create_context_profile extensions. * These attributes can be used to indicate at context creation which OpenGL interface will be used. This includes the * OpenGL version, the layer plane on which rendering takes place and also optional debug and forward combatibility modes. - * (read the XGL_create_context spec for details) + * (read the ARB_create_context spec for details) *

* Use of this class is optional. If an OpenGL context is created without passing an instance of this class - * (or XGL_create_context is not supported), the old context creation code will be used. Use of ContextAttribs is required - * to create an OpenGL 3.0 or newer context. Support for debug and forward compatible mobes is not guaranteed by the OpenGL - * implementation. Developers may encounter debug contexts being the same as non-debug contexts or forward compatible - * contexts having support for deprecated functionality. + * (or ARB_create_context is not supported), the old context creation code will be used. Support for debug and forward + * compatible mobes is not guaranteed by the OpenGL implementation. Developers may encounter debug contexts being the same + * as non-debug contexts or forward compatible contexts having support for deprecated functionality. *

* If the forwardCompatible * attribute is used, LWJGL will not load the deprecated functionality (as defined in the OpenGL 3.0 specification). This @@ -72,10 +72,10 @@ } public ContextAttribs(final int majorVersion, final int minorVersion) { - if ( majorVersion < 0 || - 3 < majorVersion || + if ( majorVersion < 0 || 4 < majorVersion || minorVersion < 0 || - (majorVersion == 3 && 2 < minorVersion) || + (majorVersion == 4 && 0 < minorVersion) || + (majorVersion == 3 && 3 < minorVersion) || (majorVersion == 2 && 1 < minorVersion) || (majorVersion == 1 && 5 < minorVersion) ) throw new IllegalArgumentException("Invalid OpenGL version specified: " + majorVersion + '.' + minorVersion); @@ -88,7 +88,7 @@ this.debug = false; this.forwardCompatible = false; - this.profileCore = 3 < majorVersion || (majorVersion == 3 && 2 <= minorVersion) ? true : false; + this.profileCore = false; this.profileCompatibility = false; } diff --git a/src/java/org/lwjgl/opengl/Display.java b/src/java/org/lwjgl/opengl/Display.java index b344ef1..e90db80 100644 --- a/src/java/org/lwjgl/opengl/Display.java +++ b/src/java/org/lwjgl/opengl/Display.java @@ -106,14 +106,10 @@ /** Swap interval */ private static int swap_interval; - /** A unique context object, so we can track different contexts between creates() and destroys() */ - private static PeerInfo peer_info; - private static Context context; - /** The Drawable instance that tracks the current Display context */ - private final static Drawable drawable; - - private static boolean window_created = false; + private static final AbstractDrawable drawable; + + private static boolean window_created; private static boolean parent_resized; @@ -137,10 +133,19 @@ } catch (LWJGLException e) { throw new RuntimeException(e); } - drawable = new Drawable() { - public Context getContext() { + drawable = new AbstractDrawable() { + public void destroy() { synchronized ( GlobalLock.lock ) { - return isCreated() ? context : null; + if ( !isCreated() ) + return; + + releaseDrawable(); + super.destroy(); + destroyWindow(); + x = y = -1; + cached_icons = null; + reset(); + removeShutdownHook(); } } }; @@ -238,24 +243,23 @@ * @throws LWJGLException if the display mode could not be set */ public static void setDisplayMode(DisplayMode mode) throws LWJGLException { - synchronized (GlobalLock.lock) { - if (mode == null) + synchronized ( GlobalLock.lock ) { + if ( mode == null ) throw new NullPointerException("mode must be non-null"); boolean was_fullscreen = isFullscreen(); current_mode = mode; - if (isCreated()) { + if ( isCreated() ) { destroyWindow(); // If mode is not fullscreen capable, make sure we are in windowed mode try { - if (was_fullscreen && !isFullscreen()) + if ( was_fullscreen && !isFullscreen() ) display_impl.resetDisplayMode(); - else if (isFullscreen()) + else if ( isFullscreen() ) switchDisplayMode(); createWindow(); makeCurrentAndSetSwapInterval(); } catch (LWJGLException e) { - destroyContext(); - destroyPeerInfo(); + drawable.destroy(); display_impl.resetDisplayMode(); throw e; } @@ -268,9 +272,9 @@ } private static int getWindowX() { - if (!isFullscreen() && parent == null) { + if ( !isFullscreen() && parent == null ) { // if no display location set, center window - if (x == -1) { + if ( x == -1 ) { return Math.max(0, (initial_mode.getWidth() - current_mode.getWidth()) / 2); } else { return x; @@ -281,7 +285,7 @@ } private static int getWindowY() { - if (!isFullscreen() && parent == null) { + if ( !isFullscreen() && parent == null ) { // if no display location set, center window if ( y == -1 ) { return Math.max(0, (initial_mode.getHeight() - current_mode.getHeight()) / 2); @@ -324,6 +328,7 @@ private static void releaseDrawable() { try { + Context context = drawable.context; if ( context != null && context.isCurrent() ) { Context.releaseCurrentContext(); context.releaseDrawable(); @@ -419,12 +424,13 @@ savedTimeLate = timeLate; } - while ( gapTo > timeNow + savedTimeLate ) { - try { + try { + while ( gapTo > timeNow + savedTimeLate ) { Thread.sleep(1); - } catch (InterruptedException e) { - } - timeNow = Sys.getTime(); + timeNow = Sys.getTime(); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); } synchronized ( GlobalLock.lock ) { @@ -463,13 +469,13 @@ */ public static void setParent(Canvas parent) throws LWJGLException { synchronized ( GlobalLock.lock ) { - if (Display.parent != parent) { + if ( Display.parent != parent ) { Display.parent = parent; if ( !isCreated() ) return; destroyWindow(); try { - if (isFullscreen()) { + if ( isFullscreen() ) { switchDisplayMode(); } else { display_impl.resetDisplayMode(); @@ -477,8 +483,7 @@ createWindow(); makeCurrentAndSetSwapInterval(); } catch (LWJGLException e) { - destroyContext(); - destroyPeerInfo(); + drawable.destroy(); display_impl.resetDisplayMode(); throw e; } @@ -519,18 +524,18 @@ 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"); DisplayMode old_mode = current_mode; current_mode = mode; boolean was_fullscreen = isFullscreen(); Display.fullscreen = fullscreen; - if (was_fullscreen != isFullscreen() || !mode.equals(old_mode)) { - if (!isCreated()) + if ( was_fullscreen != isFullscreen() || !mode.equals(old_mode) ) { + if ( !isCreated() ) return; destroyWindow(); try { - if (isFullscreen()) { + if ( isFullscreen() ) { switchDisplayMode(); } else { display_impl.resetDisplayMode(); @@ -538,8 +543,7 @@ createWindow(); makeCurrentAndSetSwapInterval(); } catch (LWJGLException e) { - destroyContext(); - destroyPeerInfo(); + drawable.destroy(); display_impl.resetDisplayMode(); throw e; } @@ -549,7 +553,7 @@ /** @return whether the Display is in fullscreen mode */ public static boolean isFullscreen() { - synchronized (GlobalLock.lock) { + synchronized ( GlobalLock.lock ) { return fullscreen && current_mode.isFullscreenCapable(); } } @@ -651,7 +655,6 @@ * Update the window. If the window is visible clears * the dirty flag and calls swapBuffers() and finally * polls the input devices. - * */ public static void update() { update(true); @@ -710,12 +713,12 @@ * @throws LWJGLException If the context could not be released */ public static void releaseContext() throws LWJGLException { - synchronized ( GlobalLock.lock ) { - if ( !isCreated() ) - throw new IllegalStateException("Display is not created"); - if ( context.isCurrent() ) - Context.releaseCurrentContext(); - } + drawable.releaseContext(); + } + + /** Returns true if the Display's context is current in the current thread. */ + public static boolean isCurrent() throws LWJGLException { + return drawable.isCurrent(); } /** @@ -724,11 +727,7 @@ * @throws LWJGLException If the context could not be made current */ public static void makeCurrent() throws LWJGLException { - synchronized ( GlobalLock.lock ) { - if ( !isCreated() ) - throw new IllegalStateException("Display is not created"); - context.makeCurrent(); - } + drawable.makeCurrent(); } private static void removeShutdownHook() { @@ -848,19 +847,19 @@ throw new NullPointerException("pixel_format cannot be null"); removeShutdownHook(); registerShutdownHook(); - if (isFullscreen()) + if ( isFullscreen() ) switchDisplayMode(); try { - peer_info = display_impl.createPeerInfo(pixel_format); + drawable.peer_info = display_impl.createPeerInfo(pixel_format); try { createWindow(); try { - context = new Context(peer_info, attribs, shared_drawable != null ? shared_drawable.getContext() : null); + drawable.context = new Context(drawable.peer_info, attribs, shared_drawable != null ? ((AbstractDrawable)shared_drawable).getContext() : null); try { makeCurrentAndSetSwapInterval(); initContext(); } catch (LWJGLException e) { - destroyContext(); + drawable.destroy(); throw e; } } catch (LWJGLException e) { @@ -868,7 +867,7 @@ throw e; } } catch (LWJGLException e) { - destroyPeerInfo(); + drawable.destroy(); throw e; } } catch (LWJGLException e) { @@ -879,13 +878,13 @@ } /** - * Set the initial color of the Display. This method is called before the Display is created and will set the - * background color to the one specified in this method. - * - * @param red - color value between 0 - 1 - * @param green - color value between 0 - 1 - * @param blue - color value between 0 - 1 - */ + * Set the initial color of the Display. This method is called before the Display is created and will set the + * background color to the one specified in this method. + * + * @param red - color value between 0 - 1 + * @param green - color value between 0 - 1 + * @param blue - color value between 0 - 1 + */ public static void setInitialBackground(float red, float green, float blue) { r = red; g = green; @@ -957,41 +956,14 @@ * regardless of whether the Display was the current rendering context. */ public static void destroy() { - synchronized ( GlobalLock.lock ) { - if ( !isCreated() ) { - return; - } - - releaseDrawable(); - destroyContext(); - destroyWindow(); - destroyPeerInfo(); - x = y = -1; - cached_icons = null; - reset(); - removeShutdownHook(); - } - } - - private static void destroyPeerInfo() { - peer_info.destroy(); - peer_info = null; - } - - private static void destroyContext() { - try { - context.forceDestroy(); - } catch (LWJGLException e) { - throw new RuntimeException(e); - } finally { - context = null; - } + drawable.destroy(); } /* * Reset display mode if fullscreen. This method is also called from the shutdown hook added * in the static constructor */ + private static void reset() { display_impl.resetDisplayMode(); current_mode = initial_mode; @@ -1050,7 +1022,7 @@ y = new_y; // offset if already created - if (isCreated() && !isFullscreen()) { + if ( isCreated() && !isFullscreen() ) { reshape(); } } diff --git a/src/java/org/lwjgl/opengl/Drawable.java b/src/java/org/lwjgl/opengl/Drawable.java index 8e542f1..84327aa 100644 --- a/src/java/org/lwjgl/opengl/Drawable.java +++ b/src/java/org/lwjgl/opengl/Drawable.java @@ -31,6 +31,8 @@ */ package org.lwjgl.opengl; +import org.lwjgl.LWJGLException; + /** * The Drawable interface describes an OpenGL drawable with an associated * Context. @@ -39,5 +41,25 @@ */ public interface Drawable { - Context getContext(); + + /** Returns true if the Drawable's context is current in the current thread. */ + boolean isCurrent() throws LWJGLException; + + /** + * Makes the Drawable's context current in the current thread. + * + * @throws LWJGLException + */ + void makeCurrent() throws LWJGLException; + + /** + * If the Drawable's context is current in the current thread, no context will be current after a call to this method. + * + * @throws LWJGLException + */ + void releaseContext() throws LWJGLException; + + /** Destroys the Drawable. */ + void destroy(); + } diff --git a/src/java/org/lwjgl/opengl/DrawableLWJGL.java b/src/java/org/lwjgl/opengl/DrawableLWJGL.java new file mode 100644 index 0000000..b79c806 --- /dev/null +++ b/src/java/org/lwjgl/opengl/DrawableLWJGL.java @@ -0,0 +1,24 @@ +package org.lwjgl.opengl; + +import org.lwjgl.LWJGLException; + +/** + * @author Spasi + */ +interface DrawableLWJGL extends Drawable { + + /** + * [INTERNAL USE ONLY] Returns the Drawable's Context. + * + * @return the Drawable's Context + */ + Context getContext(); + + /** + * [INTERNAL USE ONLY] Creates a new Context that is shared with the Drawable's Context. + * + * @return a Context shared with the Drawable's Context. + */ + Context createSharedContext() throws LWJGLException; + +} diff --git a/src/java/org/lwjgl/opengl/GLChecks.java b/src/java/org/lwjgl/opengl/GLChecks.java index b2d2339..ca0116e 100644 --- a/src/java/org/lwjgl/opengl/GLChecks.java +++ b/src/java/org/lwjgl/opengl/GLChecks.java @@ -35,6 +35,7 @@ import java.nio.IntBuffer; import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLUtil; /** * A class to check buffer boundaries in GL methods. Many GL @@ -46,8 +47,8 @@ * Thrown by the debug build library of the LWJGL if any OpenGL operation causes an error. * * @author cix_foo - * @version $Revision: 3279 $ - * $Id: GLChecks.java 3279 2010-03-11 21:06:49Z spasi $ + * @version $Revision: 3334 $ + * $Id: GLChecks.java 3334 2010-04-22 23:21:48Z spasi $ */ class GLChecks { @@ -60,93 +61,78 @@ } static int getBufferObjectSize(ContextCapabilities caps, int buffer_enum) { - IntBuffer scratch_buffer = caps.scratch_int_buffer; - GL15.glGetBufferParameter(buffer_enum, GL15.GL_BUFFER_SIZE, scratch_buffer); - return scratch_buffer.get(0); + return GL15.glGetBufferParameter(buffer_enum, GL15.GL_BUFFER_SIZE); } static int getBufferObjectSizeARB(ContextCapabilities caps, int buffer_enum) { - IntBuffer scratch_buffer = caps.scratch_int_buffer; - ARBBufferObject.glGetBufferParameterARB(buffer_enum, ARBBufferObject.GL_BUFFER_SIZE_ARB, scratch_buffer); - return scratch_buffer.get(0); + return ARBBufferObject.glGetBufferParameterARB(buffer_enum, ARBBufferObject.GL_BUFFER_SIZE_ARB); } static int getBufferObjectSizeATI(ContextCapabilities caps, int buffer) { - IntBuffer scratch_buffer = caps.scratch_int_buffer; - ATIVertexArrayObject.glGetObjectBufferATI(buffer, ATIVertexArrayObject.GL_OBJECT_BUFFER_SIZE_ATI, scratch_buffer); - return scratch_buffer.get(0); + return ATIVertexArrayObject.glGetObjectBufferATI(buffer, ATIVertexArrayObject.GL_OBJECT_BUFFER_SIZE_ATI); } static int getNamedBufferObjectSize(ContextCapabilities caps, int buffer) { - IntBuffer scratch_buffer = caps.scratch_int_buffer; - EXTDirectStateAccess.glGetNamedBufferParameterEXT(buffer, GL15.GL_BUFFER_SIZE, scratch_buffer); - return scratch_buffer.get(0); - } - - private static boolean checkBufferObject(ContextCapabilities caps, int buffer_enum, boolean state) { - IntBuffer scratch_buffer = caps.scratch_int_buffer; - GL11.glGetInteger(buffer_enum, scratch_buffer); - boolean is_enabled = scratch_buffer.get(0) != 0; - return state == is_enabled; + return EXTDirectStateAccess.glGetNamedBufferParameterEXT(buffer, GL15.GL_BUFFER_SIZE); } /** Helper method to ensure that array buffer objects are disabled. If they are enabled, we'll throw an OpenGLException */ static void ensureArrayVBOdisabled(ContextCapabilities caps) { - if(StateTracker.getReferencesStack(caps).getReferences().arrayBuffer != 0) + if( LWJGLUtil.CHECKS && StateTracker.getReferencesStack(caps).getReferences().arrayBuffer != 0 ) throw new OpenGLException("Cannot use Buffers when Array Buffer Object is enabled"); } /** Helper method to ensure that array buffer objects are enabled. If they are disabled, we'll throw an OpenGLException */ static void ensureArrayVBOenabled(ContextCapabilities caps) { - if(StateTracker.getReferencesStack(caps).getReferences().arrayBuffer == 0) + if( LWJGLUtil.CHECKS && StateTracker.getReferencesStack(caps).getReferences().arrayBuffer == 0 ) throw new OpenGLException("Cannot use offsets when Array Buffer Object is disabled"); } /** Helper method to ensure that element array buffer objects are disabled. If they are enabled, we'll throw an OpenGLException */ static void ensureElementVBOdisabled(ContextCapabilities caps) { - if(StateTracker.getReferencesStack(caps).getReferences().elementArrayBuffer != 0) + if( LWJGLUtil.CHECKS && StateTracker.getReferencesStack(caps).getReferences().elementArrayBuffer != 0 ) throw new OpenGLException("Cannot use Buffers when Element Array Buffer Object is enabled"); } /** Helper method to ensure that element array buffer objects are enabled. If they are disabled, we'll throw an OpenGLException */ static void ensureElementVBOenabled(ContextCapabilities caps) { - if(StateTracker.getReferencesStack(caps).getReferences().elementArrayBuffer == 0) + if( LWJGLUtil.CHECKS && StateTracker.getReferencesStack(caps).getReferences().elementArrayBuffer == 0 ) throw new OpenGLException("Cannot use offsets when Element Array Buffer Object is disabled"); } /** Helper method to ensure that array buffer objects are disabled. If they are enabled, we'll throw an OpenGLException */ static void ensureIndirectBOdisabled(ContextCapabilities caps) { - if ( StateTracker.getReferencesStack(caps).getReferences().indirectBuffer != 0 ) + if ( LWJGLUtil.CHECKS && StateTracker.getReferencesStack(caps).getReferences().indirectBuffer != 0 ) throw new OpenGLException("Cannot use Buffers when Draw Indirect Object is enabled"); } /** Helper method to ensure that array buffer objects are enabled. If they are disabled, we'll throw an OpenGLException */ static void ensureIndirectBOenabled(ContextCapabilities caps) { - if ( StateTracker.getReferencesStack(caps).getReferences().indirectBuffer == 0 ) + if ( LWJGLUtil.CHECKS && StateTracker.getReferencesStack(caps).getReferences().indirectBuffer == 0 ) throw new OpenGLException("Cannot use offsets when Draw Indirect Object is disabled"); } /** Helper method to ensure that pixel pack buffer objects are disabled. If they are enabled, we'll throw an OpenGLException */ static void ensurePackPBOdisabled(ContextCapabilities caps) { - if ( StateTracker.getReferencesStack(caps).getReferences().pixelPackBuffer != 0 ) + if ( LWJGLUtil.CHECKS && StateTracker.getReferencesStack(caps).getReferences().pixelPackBuffer != 0 ) throw new OpenGLException("Cannot use Buffers when Pixel Pack Buffer Object is enabled"); } /** Helper method to ensure that pixel pack buffer objects are enabled. If they are disabled, we'll throw an OpenGLException */ static void ensurePackPBOenabled(ContextCapabilities caps) { - if ( StateTracker.getReferencesStack(caps).getReferences().pixelPackBuffer == 0 ) + if ( LWJGLUtil.CHECKS && StateTracker.getReferencesStack(caps).getReferences().pixelPackBuffer == 0 ) throw new OpenGLException("Cannot use offsets when Pixel Pack Buffer Object is disabled"); } /** Helper method to ensure that pixel unpack buffer objects are disabled. If they are enabled, we'll throw an OpenGLException */ static void ensureUnpackPBOdisabled(ContextCapabilities caps) { - if ( StateTracker.getReferencesStack(caps).getReferences().pixelUnpackBuffer != 0 ) + if ( LWJGLUtil.CHECKS && StateTracker.getReferencesStack(caps).getReferences().pixelUnpackBuffer != 0 ) throw new OpenGLException("Cannot use Buffers when Pixel Unpack Buffer Object is enabled"); } /** Helper method to ensure that pixel unpack buffer objects are enabled. If they are disabled, we'll throw an OpenGLException */ static void ensureUnpackPBOenabled(ContextCapabilities caps) { - if ( StateTracker.getReferencesStack(caps).getReferences().pixelUnpackBuffer == 0 ) + if ( LWJGLUtil.CHECKS && StateTracker.getReferencesStack(caps).getReferences().pixelUnpackBuffer == 0 ) throw new OpenGLException("Cannot use offsets when Pixel Unpack Buffer Object is disabled"); } @@ -162,19 +148,19 @@ * @return the size, in elements, of the image */ static int calculateImageStorage(Buffer buffer, int format, int type, int width, int height, int depth) { - return calculateImageStorage(format, type, width, height, depth) >> BufferUtils.getElementSizeExponent(buffer); + return LWJGLUtil.CHECKS ? calculateImageStorage(format, type, width, height, depth) >> BufferUtils.getElementSizeExponent(buffer) : 0; } static int calculateTexImage1DStorage(Buffer buffer, int format, int type, int width) { - return calculateTexImage1DStorage(format, type, width) >> BufferUtils.getElementSizeExponent(buffer); + return LWJGLUtil.CHECKS ? calculateTexImage1DStorage(format, type, width) >> BufferUtils.getElementSizeExponent(buffer) : 0; } static int calculateTexImage2DStorage(Buffer buffer, int format, int type, int width, int height) { - return calculateTexImage2DStorage(format, type, width, height) >> BufferUtils.getElementSizeExponent(buffer); + return LWJGLUtil.CHECKS ? calculateTexImage2DStorage(format, type, width, height) >> BufferUtils.getElementSizeExponent(buffer) : 0; } static int calculateTexImage3DStorage(Buffer buffer, int format, int type, int width, int height, int depth) { - return calculateTexImage3DStorage(format, type, width, height, depth) >> BufferUtils.getElementSizeExponent(buffer); + return LWJGLUtil.CHECKS ? calculateTexImage3DStorage(format, type, width, height, depth) >> BufferUtils.getElementSizeExponent(buffer) : 0; } /** diff --git a/src/java/org/lwjgl/opengl/GLContext.java b/src/java/org/lwjgl/opengl/GLContext.java index f98c41f..f315894 100644 --- a/src/java/org/lwjgl/opengl/GLContext.java +++ b/src/java/org/lwjgl/opengl/GLContext.java @@ -54,8 +54,8 @@ * That way, multiple threads can have multiple contexts current and render to them concurrently. * * @author elias_naur - * @version $Revision: 3279 $ - * $Id: GLContext.java 3279 2010-03-11 21:06:49Z spasi $ + * @version $Revision: 3355 $ + * $Id: GLContext.java 3355 2010-05-27 22:56:29Z spasi $ */ public final class GLContext { @@ -169,6 +169,22 @@ return 0; } + /** + * Helper method to get a pointer to a named function with aliases in the OpenGL library. + * + * @param aliases the function name aliases. + * + * @return the function pointer address + */ + static long getFunctionAddress(String[] aliases) { + for ( int i = 0; i < aliases.length; i++ ) { + long address = getFunctionAddress(aliases[i]); + if ( address != 0 ) + return address; + } + return 0; + } + /** Helper method to get a pointer to a named function in the OpenGL library */ static native long getFunctionAddress(String name); diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index 61332e8..6721692 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -39,6 +39,9 @@ */ import java.awt.Canvas; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; @@ -47,6 +50,12 @@ import org.lwjgl.LWJGLException; import org.lwjgl.LWJGLUtil; import org.lwjgl.opengl.XRandR.Screen; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; final class LinuxDisplay implements DisplayImplementation { /* X11 constants */ @@ -407,7 +416,15 @@ ByteBuffer handle = peer_info.lockAndGetHandle(); try { current_window_mode = getWindowMode(Display.isFullscreen()); - boolean undecorated = Display.getPrivilegedBoolean("org.lwjgl.opengl.Window.undecorated") || current_window_mode != WINDOWED; + // Try to enable Lecagy FullScreen Support in Compiz, else + // we may have trouble with stuff overlapping our fullscreen window. + if ( current_window_mode != WINDOWED ) + Compiz.setLegacyFullscreenSupport(true); + // Setting _MOTIF_WM_HINTS in fullscreen mode is problematic for certain window + // managers. We do not set MWM_HINTS_DECORATIONS in fullscreen mode anymore, + // unless org.lwjgl.opengl.Window.undecorated_fs has been specified. + // See native/linux/org_lwjgl_opengl_Display.c, createWindow function. + boolean undecorated = Display.getPrivilegedBoolean("org.lwjgl.opengl.Window.undecorated") || (current_window_mode != WINDOWED && Display.getPrivilegedBoolean("org.lwjgl.opengl.Window.undecorated_fs")); this.parent = parent; parent_window = parent != null ? getHandle(parent) : getRootWindow(getDisplay(), getDefaultScreen()); current_window = nCreateWindow(getDisplay(), getDefaultScreen(), handle, mode, current_window_mode, x, y, undecorated, parent_window); @@ -441,7 +458,7 @@ private static native void mapRaised(long display, long window); private static native void reparentWindow(long display, long window, long parent, int x, int y); - private boolean isAncestorXEmbedded(long window) throws LWJGLException { + private static boolean isAncestorXEmbedded(long window) throws LWJGLException { long xembed_atom = internAtom("_XEMBED_INFO", true); if (xembed_atom != None) { long w = window; @@ -483,6 +500,9 @@ ungrabKeyboard(); nDestroyWindow(getDisplay(), getWindow()); decDisplay(); + + if ( current_window_mode != WINDOWED ) + Compiz.setLegacyFullscreenSupport(false); } finally { unlockAWT(); } @@ -524,7 +544,12 @@ try { if( current_displaymode_extension == XRANDR && savedXrandrConfig.length > 0 ) { - XRandR.setConfiguration( savedXrandrConfig ); + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + XRandR.setConfiguration( savedXrandrConfig ); + return null; + } + }); } else { @@ -532,6 +557,8 @@ } if (isXF86VidModeSupported()) doSetGamma(saved_gamma); + + Compiz.setLegacyFullscreenSupport(false); } catch (LWJGLException e) { LWJGLUtil.log("Caught exception while resetting mode: " + e); } finally { @@ -606,6 +633,8 @@ public DisplayMode init() throws LWJGLException { lockAWT(); try { + Compiz.init(); + delete_atom = internAtom("WM_DELETE_WINDOW", false); current_displaymode_extension = getBestDisplayModeExtension(); if (current_displaymode_extension == NONE) @@ -615,7 +644,11 @@ throw new LWJGLException("No modes available"); switch (current_displaymode_extension) { case XRANDR: - savedXrandrConfig = XRandR.getConfiguration(); + savedXrandrConfig = (Screen[])AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return XRandR.getConfiguration(); + } + }); saved_mode = getCurrentXRandrMode(); break; case XF86VIDMODE: @@ -847,12 +880,12 @@ setInputFocusUnsafe(current_window); } else if (xembedded) { - setInputFocusUnsafe(0); - } - } - else if (parent_focus && !focused) { - setInputFocusUnsafe(current_window); - } + setInputFocusUnsafe(1); + } + } + //else if (parent_focus && !focused && !xembedded) { + // setInputFocusUnsafe(current_window); + //} } private void setFocused(boolean got_focus, int focus_detail) { @@ -890,7 +923,12 @@ try { if( current_displaymode_extension == XRANDR && savedXrandrConfig.length > 0 ) { - XRandR.setConfiguration( savedXrandrConfig ); + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + XRandR.setConfiguration( savedXrandrConfig ); + return null; + } + }); } else { @@ -1212,4 +1250,193 @@ public boolean isInsideWindow() { return true; } -} + + /** + * Helper class for managing Compiz's workarounds. We need this to enable Legacy + * Fullscreen Support in Compiz, else we'll have trouble with fullscreen windows + * when Compiz effects are enabled. + * + * Implementation Note: This code is probably too much for an inner class, but + * keeping it here until we're sure we cannot find a better solution. + */ + private static final class Compiz { + + private static boolean applyFix; + + private static Provider provider; + + private Compiz() { + } + + static void init() { + if ( Display.getPrivilegedBoolean("org.lwjgl.opengl.Window.nocompiz_lfs") ) + return; + + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + // Check if Compiz is active + if ( !isProcessActive("compiz") ) + return null; + + provider = null; + + String providerName = null; + + // Check if Dbus is available + if ( isProcessActive("dbus-daemon") ) { + providerName = "Dbus"; + provider = new Provider() { + + private static final String KEY = "/org/freedesktop/compiz/workarounds/allscreens/legacy_fullscreen"; + + public boolean hasLegacyFullscreenSupport() throws LWJGLException { + final List output = Compiz.run(new String[] { + "dbus-send", "--print-reply", "--type=method_call", "--dest=org.freedesktop.compiz", KEY, "org.freedesktop.compiz.get" + }); + + if ( output == null || output.size() < 2 ) + throw new LWJGLException("Invalid Dbus reply."); + + String line = (String)output.get(0); + + if ( !line.startsWith("method return") ) + throw new LWJGLException("Invalid Dbus reply."); + + line = ((String)output.get(1)).trim(); // value + if ( !line.startsWith("boolean") || line.length() < 12) + throw new LWJGLException("Invalid Dbus reply."); + + return "true".equalsIgnoreCase(line.substring("boolean".length() + 1)); + } + + public void setLegacyFullscreenSupport(final boolean state) throws LWJGLException { + if ( Compiz.run(new String[] { + "dbus-send", "--type=method_call", "--dest=org.freedesktop.compiz", KEY, "org.freedesktop.compiz.set", "boolean:" + Boolean.toString(state) + }) == null ) + throw new LWJGLException("Failed to apply Compiz LFS workaround."); + } + }; + } else { + try { + // Check if Gconf is available + Runtime.getRuntime().exec("gconftool"); + + providerName = "gconftool"; + provider = new Provider() { + + private static final String KEY = "/apps/compiz/plugins/workarounds/allscreens/options/legacy_fullscreen"; + + public boolean hasLegacyFullscreenSupport() throws LWJGLException { + final List output = Compiz.run(new String[] { + "gconftool", "-g", KEY + }); + + if ( output == null || output.size() == 0 ) + throw new LWJGLException("Invalid gconftool reply."); + + return Boolean.parseBoolean(((String)output.get(0)).trim()); + } + + public void setLegacyFullscreenSupport(final boolean state) throws LWJGLException { + if ( Compiz.run(new String[] { + "gconftool", "-s", KEY, "-s", Boolean.toString(state), "-t", "bool" + }) == null ) + throw new LWJGLException("Failed to apply Compiz LFS workaround."); + + if ( state ) { + try { + // gconftool will not apply the workaround immediately, sleep a bit + // to make sure it will be ok when we create the window. + Thread.sleep(200); // 100 is too low, 150 works, set to 200 to be safe. + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }; + } catch (IOException e) { + // Ignore + } + } + + if ( provider != null && !provider.hasLegacyFullscreenSupport() ) { // No need to do anything if LFS is already enabled. + applyFix = true; + LWJGLUtil.log("Using " + providerName + " to apply Compiz LFS workaround."); + } + } catch (LWJGLException e) { + // Ignore + } finally { + return null; + } + } + }); + } + + static void setLegacyFullscreenSupport(final boolean enabled) { + if ( !applyFix ) + return; + + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + provider.setLegacyFullscreenSupport(enabled); + } catch (LWJGLException e) { + LWJGLUtil.log("Failed to change Compiz Legacy Fullscreen Support. Reason: " + e.getMessage()); + } + return null; + } + }); + } + + private static List run(final String[] command) throws LWJGLException { + final List output = new ArrayList(); + + try { + final Process p = Runtime.getRuntime().exec(command); + try { + final int exitValue = p.waitFor(); + if ( exitValue != 0 ) + return null; + } catch (InterruptedException e) { + throw new LWJGLException("Process interrupted.", e); + } + + final BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); + + String line; + while ( (line = br.readLine()) != null ) + output.add(line); + + br.close(); + } catch (final IOException e) { + throw new LWJGLException("Process failed.", e); + } + + return output; + } + + private static boolean isProcessActive(final String processName) throws LWJGLException { + final List output = run(new String[] { "ps", "-C", processName }); + if ( output == null ) + return false; + + for ( Iterator iter = output.iterator(); iter.hasNext(); ) { + final String line = (String)iter.next(); + if ( line.contains(processName) ); + return true; + } + + return false; + } + + private interface Provider { + + boolean hasLegacyFullscreenSupport() throws LWJGLException; + + void setLegacyFullscreenSupport(boolean state) throws LWJGLException; + + } + } + +} \ No newline at end of file diff --git a/src/java/org/lwjgl/opengl/MacOSXDisplay.java b/src/java/org/lwjgl/opengl/MacOSXDisplay.java index 25be1ba..ea58d0e 100644 --- a/src/java/org/lwjgl/opengl/MacOSXDisplay.java +++ b/src/java/org/lwjgl/opengl/MacOSXDisplay.java @@ -78,7 +78,7 @@ AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws Exception { Application.getApplication().addApplicationListener(new ApplicationAdapter() { - public final void handleQuit(ApplicationEvent event) { + public void handleQuit(ApplicationEvent event) { doHandleQuit(); } }); @@ -271,15 +271,16 @@ * * - elias */ + AbstractDrawable drawable = (AbstractDrawable)Display.getDrawable(); if (Display.isFullscreen() && (frame != null && frame.getCanvas().syncCanvasPainted() || should_update)) { try { - MacOSXContextImplementation.resetView(Display.getDrawable().getContext().getPeerInfo(), Display.getDrawable().getContext()); + MacOSXContextImplementation.resetView(drawable.peer_info, drawable.context); } catch (LWJGLException e) { LWJGLUtil.log("Failed to reset context: " + e); } } if (should_update) { - Display.getDrawable().getContext().update(); + drawable.context.update(); /* This is necessary to make sure the context won't "forget" about the view size */ GL11.glGetInteger(GL11.GL_VIEWPORT, current_viewport); GL11.glViewport(current_viewport.get(0), current_viewport.get(1), current_viewport.get(2), current_viewport.get(3)); diff --git a/src/java/org/lwjgl/opengl/Pbuffer.java b/src/java/org/lwjgl/opengl/Pbuffer.java index 877b192..e11b7c6 100644 --- a/src/java/org/lwjgl/opengl/Pbuffer.java +++ b/src/java/org/lwjgl/opengl/Pbuffer.java @@ -35,7 +35,6 @@ import org.lwjgl.BufferUtils; import org.lwjgl.LWJGLException; -import org.lwjgl.LWJGLUtil; import org.lwjgl.Sys; /** @@ -46,10 +45,10 @@ * This class is thread-safe. * * @author elias_naur - * @version $Revision: 3116 $ - * $Id: Pbuffer.java 3116 2008-08-19 16:46:03Z spasi $ + * @version $Revision: 3334 $ + * $Id: Pbuffer.java 3334 2010-04-22 23:21:48Z spasi $ */ -public final class Pbuffer implements Drawable { +public final class Pbuffer extends AbstractDrawable { /** * Indicates that Pbuffers can be created. */ @@ -136,11 +135,6 @@ public static final int DEPTH_BUFFER = RenderTexture.WGL_DEPTH_COMPONENT_NV; /** - * Handle to the native GL rendering context - */ - private final PeerInfo peer_info; - - /** * Width */ private final int width; @@ -149,10 +143,6 @@ * Height */ private final int height; - - private final Context context; - - private boolean destroyed; static { Sys.initialize(); @@ -227,14 +217,11 @@ this.width = width; this.height = height; this.peer_info = createPbuffer(width, height, pixel_format, renderTexture); - Context shared_context = null; - if (shared_drawable != null) { - shared_context = shared_drawable.getContext(); - } else { - Drawable display_drawable = Display.getDrawable(); - if (display_drawable != null) - shared_context = display_drawable.getContext(); - } + Context shared_context; + if (shared_drawable != null) + shared_context = ((DrawableLWJGL)shared_drawable).getContext(); + else + shared_context = ((DrawableLWJGL)Display.getDrawable()).getContext(); // May be null this.context = new Context(peer_info, attribs, shared_context); } @@ -251,15 +238,6 @@ renderTexture.pBufferAttribs); } - public Context getContext() { - return context; - } - - private void checkDestroyed() { - if (destroyed) - throw new IllegalStateException("Pbuffer is destroyed"); - } - /** * Method to test for validity of the buffer. If this function returns true, the buffer contents is lost. The buffer can still * be used, but the results are undefined. The application is expected to release the buffer if needed, destroy it and recreate @@ -273,37 +251,12 @@ } /** - * Method to make the Pbuffer context current. All subsequent OpenGL calls will go to this buffer. - * @throws LWJGLException if the context could not be made current - */ - public synchronized void makeCurrent() throws LWJGLException { - checkDestroyed(); - context.makeCurrent(); - } - - /** * Gets the Pbuffer capabilities. * * @return a bitmask of Pbuffer capabilities. */ public static int getCapabilities() { return Display.getImplementation().getPbufferCapabilities(); - } - - /** - * Destroys the Pbuffer. After this call, there will be no valid GL rendering context - regardless of whether this Pbuffer was - * the current rendering context or not. - */ - public synchronized void destroy() { - if (destroyed) - return; - try { - context.forceDestroy(); - peer_info.destroy(); - destroyed = true; - } catch (LWJGLException e) { - LWJGLUtil.log("Exception occurred while destroying pbuffer: " + e); - } } // ----------------------------------------------------------------------------------------- diff --git a/src/java/org/lwjgl/opengl/PixelFormat.java b/src/java/org/lwjgl/opengl/PixelFormat.java index 5219367..7c11bfb 100644 --- a/src/java/org/lwjgl/opengl/PixelFormat.java +++ b/src/java/org/lwjgl/opengl/PixelFormat.java @@ -45,7 +45,7 @@ * pixel format selection path, which could trigger a crash. * * @author elias_naur@sourceforge.net - * @version $Revision: 3116 $ + * @version $Revision: 3355 $ */ public final class PixelFormat { @@ -66,6 +66,14 @@ * 0 means that anti-aliasing is disabled. */ private int samples; + /** + * The number of COLOR_SAMPLES_NV to use for Coverage Sample Anti-aliasing (CSAA). + * When this number is greater than 0, the {@code samples} property will be treated + * as if it were the COVERAGE_SAMPLES_NV property. + *

+ * This property is currently a no-op for the MacOS implementation. + */ + private int colorSamples; /** The number of auxiliary buffers */ private int num_aux_buffers; /** The number of bits per pixel in the accumulation buffer */ @@ -76,9 +84,15 @@ private boolean stereo; /** Whether this format specifies a floating point format */ private boolean floating_point; - /** Whether this format specifies a packed floating point format (32 bit unsigned - R11F_G11F_B10F) */ + /** + * Whether this format specifies a packed floating point format (32 bit unsigned - R11F_G11F_B10F) + * This property is currently a no-op for the MacOS implementation. + */ private boolean floating_point_packed; - /** Whether this format specifies an sRGB format */ + /** + * Whether this format specifies an sRGB format + * This property is currently a no-op for the MacOS implementation. + */ private boolean sRGB; /** @@ -132,6 +146,7 @@ this.stencil = pf.stencil; this.samples = pf.samples; + this.colorSamples = pf.colorSamples; this.num_aux_buffers = pf.num_aux_buffers; @@ -245,6 +260,38 @@ return pf; } + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new color samples values. + * A value greater than 0 is valid only if the {@code samples} property is also greater than 0. Additionally, the + * color samples value needs to be lower than or equal to the {@code samples} property. + * + * @param colorSamples the new color samples value. + * + * @return the new PixelFormat + */ + public PixelFormat withCoverageSamples(final int colorSamples) { + return withCoverageSamples(colorSamples, samples); + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new color samples + * and coverage samples values. + * + * @param colorSamples the new color samples value. This value must be lower than or equal to the coverage samples value. + * @param coverageSamples the new coverage samples value. + * + * @return the new PixelFormat + */ + public PixelFormat withCoverageSamples(final int colorSamples, final int coverageSamples) { + if ( coverageSamples < 0 || colorSamples < 0 || (coverageSamples == 0 && 0 < colorSamples) || coverageSamples < colorSamples ) + throw new IllegalArgumentException("Invalid number of coverage samples specified: " + coverageSamples + " - " + colorSamples); + + final PixelFormat pf = new PixelFormat(this); + pf.samples = coverageSamples; + pf.colorSamples = colorSamples; + return pf; + } + public int getAuxBuffers() { return num_aux_buffers; } diff --git a/src/java/org/lwjgl/opengl/SharedDrawable.java b/src/java/org/lwjgl/opengl/SharedDrawable.java new file mode 100644 index 0000000..f96d0f6 --- /dev/null +++ b/src/java/org/lwjgl/opengl/SharedDrawable.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.LWJGLException; + +/** + * @author Spasi + */ + +/** + * A Drawable implementation that shares its context with another Drawable. This is useful + * for background loading of resources. See org.lwjgl.test.opengl.multithread.BackgroundLoad + * for an example. + * + * @author Spasi + */ +public final class SharedDrawable extends AbstractDrawable { + + public SharedDrawable(final Drawable drawable) throws LWJGLException { + this.context = ((DrawableLWJGL)drawable).createSharedContext(); + } + + public Context createSharedContext() { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/java/org/lwjgl/opengl/WindowsDisplay.java b/src/java/org/lwjgl/opengl/WindowsDisplay.java index 24b56fb..6a32c3c 100644 --- a/src/java/org/lwjgl/opengl/WindowsDisplay.java +++ b/src/java/org/lwjgl/opengl/WindowsDisplay.java @@ -437,8 +437,9 @@ * is maximized helps some gfx cards recover from fullscreen */ try { - if (Display.getDrawable().getContext() != null && Display.getDrawable().getContext().isCurrent()) - Display.getDrawable().getContext().makeCurrent(); + Context context = ((DrawableLWJGL)Display.getDrawable()).getContext(); + if (context != null && context.isCurrent()) + context.makeCurrent(); } catch (LWJGLException e) { LWJGLUtil.log("Exception occurred while trying to make context current: " + e); } @@ -973,4 +974,4 @@ return "Rect: top = " + top + " bottom = " + bottom + " left = " + left + " right = " + right; } } -} +} \ No newline at end of file diff --git a/src/java/org/lwjgl/opengl/XRandR.java b/src/java/org/lwjgl/opengl/XRandR.java index 4a6fd85..519ef62 100644 --- a/src/java/org/lwjgl/opengl/XRandR.java +++ b/src/java/org/lwjgl/opengl/XRandR.java @@ -1,33 +1,28 @@ /* - * Copyright (c) 2002-2010 LWJGL Project - * All rights reserved. - * + * Copyright (c) 2002-2010 LWJGL Project All rights reserved. * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * 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. - * - * * Neither the name of 'LWJGL' nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 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 - * 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, + * modification, are permitted provided that the following conditions + * are met: * Redistributions of source code must retain the above + * copyright 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. * Neither the name of 'LWJGL' nor the names + * of its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. 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 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 - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. */ package org.lwjgl.opengl; @@ -39,9 +34,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.security.AccessController; -import java.security.PrivilegedAction; + +import org.lwjgl.LWJGLUtil; /** * Utility for working with the xrandr commmand-line utility. Assumes @@ -49,53 +45,65 @@ * * @author ryanm */ -public class XRandR { - - private static Screen[] current; - - private static Map /* */screens; - - private static void populate() { - if (screens == null) { +public class XRandR +{ + private static Screen[] current; + + private static Map /* */screens; + + private static void populate() + { + if( screens == null ) + { screens = new HashMap/* */(); // ProcessBuilder pb = new ProcessBuilder( "xrandr", "-q" ); // pb.redirectErrorStream(); - try { + try + { // Process p= pb.start(); - Process p = Runtime.getRuntime().exec(new String[] { "xrandr", "-q"}); + Process p = Runtime.getRuntime().exec( new String[] { "xrandr", "-q" } ); List/* */currentList = new ArrayList/* */(); List/* */possibles = new ArrayList/* */(); String name = null; - BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); + BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) ); String line; - while ((line = br.readLine()) != null) { + while( ( line = br.readLine() ) != null ) + { line = line.trim(); - String[] sa = line.split("\\s+"); - - if (sa[1].equals("connected")) { + String[] sa = line.split( "\\s+" ); + + if( sa[ 1 ].equals( "connected" ) ) + { // found a new screen block - if (name != null) { - screens.put(name, possibles.toArray(new Screen[possibles.size()])); + if( name != null ) + { + screens.put( name, possibles.toArray( new Screen[ possibles.size() ] ) ); possibles.clear(); } - name = sa[0]; + name = sa[ 0 ]; // record the current config - currentList.add(new Screen(name, sa[2])); - } else if (Pattern.matches("\\d*x\\d*", sa[0])) { + parseScreen( currentList, name, sa[ 2 ] ); + } + else if( Pattern.matches( "\\d*x\\d*", sa[ 0 ] ) ) + { // found a new mode line - possibles.add(new Screen(name, sa[0])); + parseScreen( possibles, name, sa[ 0 ] ); } } - screens.put(name, possibles.toArray(new Screen[possibles.size()])); + screens.put( name, possibles.toArray( new Screen[ possibles.size() ] ) ); current = (Screen[]) currentList.toArray(new Screen[currentList.size()]); - } catch (IOException e) { - e.printStackTrace(); + } + catch( Throwable e ) + { + LWJGLUtil.log( "Exception in XRandR.populate(): " + e.getMessage() ); + screens.clear(); + current = new Screen[ 0 ]; } } } @@ -104,13 +112,9 @@ * @return The current screen configuration, or an empty array if * xrandr is not supported */ - public static Screen[] getConfiguration() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - populate(); - return null; - } - }); + public static Screen[] getConfiguration() + { + populate(); return (Screen[]) current.clone(); } @@ -118,62 +122,76 @@ /** * @param screens * The desired screen set, may not be null - */ - public static void setConfiguration(Screen[]/* ... */screens) { - if (screens.length == 0) { - throw new IllegalArgumentException("Must specify at least one screen"); + * @throws IllegalArgumentException + * if no screens are specified + */ + public static void setConfiguration( Screen[]/* ... */screens ) + { + if( screens.length == 0 ) + { + throw new IllegalArgumentException( "Must specify at least one screen" ); } List/* */cmd = new ArrayList/* */(); - cmd.add("xrandr"); + cmd.add( "xrandr" ); // switch off those in the current set not in the new set - for (int i = 0; i < current.length; i++) { + for( int i = 0; i < current.length; i++ ) + { boolean found = false; - for (int j = 0; j < screens.length; j++) { - if (screens[j].name.equals(current[i].name)) { + for( int j = 0; j < screens.length; j++ ) + { + if( screens[ j ].name.equals( current[ i ].name ) ) + { found = true; break; } } - if (!found) { - cmd.add("--output"); - cmd.add(current[i].name); - cmd.add("--off"); + if( !found ) + { + cmd.add( "--output" ); + cmd.add( current[ i ].name ); + cmd.add( "--off" ); } } // set up new set - for (int i = 0; i < screens.length; i++) { - screens[i].getArgs(cmd); - } - - try { + for( int i = 0; i < screens.length; i++ ) + { + screens[ i ].getArgs( cmd ); + } + + try + { // ProcessBuilder pb = new ProcessBuilder( cmd ); // pb.redirectErrorStream(); // Process p = pb.start(); - Process p = Runtime.getRuntime().exec((String[]) cmd.toArray(new String[cmd.size()])); + Process p = + Runtime.getRuntime().exec( ( String[] ) cmd.toArray( new String[ cmd.size() ] ) ); // no output is expected, but check anyway - BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); + BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) ); String line; - while ((line = br.readLine()) != null) { - System.out.println(line); + while( ( line = br.readLine() ) != null ) + { + LWJGLUtil.log( "Unexpected output from xrandr process: " + line ); } current = screens; - } catch (IOException e) { - e.printStackTrace(); - } - + } + catch( IOException e ) + { + LWJGLUtil.log( "XRandR exception in setConfiguration(): " + e.getMessage() ); + } } /** * @return the name of connected screens, or an empty array if * xrandr is not supported */ - public static String[] getScreenNames() { + public static String[] getScreenNames() + { populate(); - return (String[]) screens.keySet().toArray(new String[screens.size()]); + return ( String[] ) screens.keySet().toArray( new String[ screens.size() ] ); } /** @@ -181,10 +199,56 @@ * @return the possible resolutions of the named screen, or * null if there is no such screen */ - public static Screen[] getResolutions(String name) { + public static Screen[] getResolutions( String name ) + { populate(); // clone the array to prevent held copies being altered return (Screen[]) ((Screen[]) screens.get(name)).clone(); + } + + private static final Pattern SCREEN_PATTERN1 = + Pattern.compile( "^(\\d+)x(\\d+)\\+(\\d+)\\+(\\d+)$" ); + + private static final Pattern SCREEN_PATTERN2 = Pattern.compile( "^(\\d+)x(\\d+)$" ); + + /** + * Parses a screen configuration and adds it to the list if it's + * valid. + * + * @param list + * the list to add the Screen to if it's valid + * @param name + * the name of this screen + * @param what + * config string, format either widthxheight or + * widthxheight+xPos+yPos + */ + private static void parseScreen( List /* */list, String name, String what ) + { + Matcher m = SCREEN_PATTERN1.matcher( what ); + if( !m.matches() ) + { + m = SCREEN_PATTERN2.matcher( what ); + if( !m.matches() ) + { + LWJGLUtil.log( "Did not match: " + what ); + return; + } + } + int width = Integer.parseInt( m.group( 1 ) ); + int height = Integer.parseInt( m.group( 2 ) ); + int xpos, ypos; + if( m.groupCount() > 3 ) + { + xpos = Integer.parseInt( m.group( 3 ) ); + ypos = Integer.parseInt( m.group( 4 ) ); + } + else + { + xpos = 0; + ypos = 0; + } + list.add( new Screen( name, width, height, xpos, ypos ) ); } /** @@ -193,65 +257,56 @@ * * @author ryanm */ - public static class Screen implements Cloneable { - + public static class Screen implements Cloneable + { /** * Name for this output */ - public final String name; + public final String name; /** * Width in pixels */ - public final int width; + public final int width; /** * Height in pixels */ - public final int height; + public final int height; /** * Position on the x-axis, in pixels */ - public int xPos = 0; + public int xPos = 0; /** * Position on the y-axis, in pixels */ - public int yPos = 0; - - /** - * @param name - * name of the screen - * @param conf - * config string, format either widthxheight or - * widthxheight+xPos+yPos - */ - private Screen(String name, String conf) { + public int yPos = 0; + + private Screen( String name, int width, int height, int xPos, int yPos ) + { this.name = name; - - String[] sa = conf.split("\\D"); - width = Integer.parseInt(sa[0]); - height = Integer.parseInt(sa[1]); - - if (sa.length > 2) { - xPos = Integer.parseInt(sa[2]); - yPos = Integer.parseInt(sa[3]); - } - } - - private void getArgs(List/* */argList) { - argList.add("--output"); - argList.add(name); - argList.add("--mode"); - argList.add(width + "x" + height); - argList.add("--pos"); - argList.add(xPos + "x" + yPos); - } - - // @Override - public String toString() { + this.width = width; + this.height = height; + this.xPos = xPos; + this.yPos = yPos; + } + + private void getArgs( List/* */argList ) + { + argList.add( "--output" ); + argList.add( name ); + argList.add( "--mode" ); + argList.add( width + "x" + height ); + argList.add( "--pos" ); + argList.add( xPos + "x" + yPos ); + } + + //@Override + public String toString() + { return name + " " + width + "x" + height + " @ " + xPos + "x" + yPos; } } -} +} \ No newline at end of file diff --git a/src/java/org/lwjgl/test/openal/EFX10Test.java b/src/java/org/lwjgl/test/openal/EFX10Test.java new file mode 100644 index 0000000..a0ce4a5 --- /dev/null +++ b/src/java/org/lwjgl/test/openal/EFX10Test.java @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2002-2010 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.test.openal; + +import java.nio.IntBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.openal.AL; +import org.lwjgl.openal.AL10; +import org.lwjgl.openal.AL11; +import org.lwjgl.openal.ALC10; +import org.lwjgl.openal.ALCcontext; +import org.lwjgl.openal.ALCdevice; +import org.lwjgl.openal.EFX10; +import org.lwjgl.openal.EFXUtil; +import org.lwjgl.util.WaveData; + +/** + * Class with a few examples testing and demonstrating the use of the OpenAL extension ALC_EXT_EFX. + *

+ * This class is not compatible with the LWJGL debug build (lwjgl-debug.jar), as the debug build + * throws exceptions instead of alGetError checks. The redundant exception handling code was not + * added in order to keep these examples simple. + * + * @author Ciardhubh + * @version $Revision$ + * $Id$ + */ +public final class EFX10Test { + + public static void main(final String[] args) throws Exception { + silentTests(); + playbackTest(); + efxUtilTest(); + } + + /** + * Loads OpenAL and makes sure ALC_EXT_EFX is supported. + */ + private static void setupEfx() throws Exception { + // Load and create OpenAL + if (!AL.isCreated()) { + AL.create(); + } + // Query for Effect Extension + if (!ALC10.alcIsExtensionPresent(AL.getDevice(), EFX10.ALC_EXT_EFX_NAME)) { + throw new Exception("No ALC_EXT_EFX supported by driver."); + } + System.out.println("ALC_EXT_EFX found."); + } + + /** + * Runs a series of API calls similar to the tutorials in the Effects Extension Guide of the + * OpenAL SDK. Nothing is played in this method. + */ + private static void silentTests() throws Exception { + setupEfx(); + + final ALCdevice device = AL.getDevice(); + + // Create context (only necessary if LWJGL context isn't sufficient, done as example) + final IntBuffer contextAttribList = BufferUtils.createIntBuffer(8); + contextAttribList.put(ALC10.ALC_FREQUENCY); + contextAttribList.put(44100); + contextAttribList.put(ALC10.ALC_REFRESH); + contextAttribList.put(60); + contextAttribList.put(ALC10.ALC_SYNC); + contextAttribList.put(ALC10.ALC_FALSE); + contextAttribList.rewind(); + // ALC_MAX_AUXILIARY_SENDS won't go above compile-time max. Set to compile-time max if + // greater. + contextAttribList.put(EFX10.ALC_MAX_AUXILIARY_SENDS); + contextAttribList.put(2); + final ALCcontext newContext = ALC10.alcCreateContext(device, contextAttribList); + if (newContext == null) { + throw new Exception("Failed to create context."); + } + final int contextCurResult = ALC10.alcMakeContextCurrent(newContext); + if (contextCurResult == ALC10.ALC_FALSE) { + throw new Exception("Failed to make context current."); + } + + // Query EFX ALC values + System.out.println("AL_VERSION: " + AL10.alGetString(AL10.AL_VERSION)); + final IntBuffer buff = BufferUtils.createIntBuffer(1); + ALC10.alcGetInteger(device, EFX10.ALC_EFX_MAJOR_VERSION, buff); + System.out.println("ALC_EFX_MAJOR_VERSION: " + buff.get(0)); + ALC10.alcGetInteger(device, EFX10.ALC_EFX_MINOR_VERSION, buff); + System.out.println("ALC_EFX_MINOR_VERSION: " + buff.get(0)); + ALC10.alcGetInteger(device, EFX10.ALC_MAX_AUXILIARY_SENDS, buff); + final int maxAuxSends = buff.get(0); + System.out.println("ALC_MAX_AUXILIARY_SENDS: " + maxAuxSends); + + + // Try to create 4 Auxiliary Effect Slots + int numAuxSlots = 0; + final int[] auxEffectSlots = new int[4]; // try more to test + AL10.alGetError(); + for (numAuxSlots = 0; numAuxSlots < 4; numAuxSlots++) { + auxEffectSlots[numAuxSlots] = EFX10.alGenAuxiliaryEffectSlots(); + if (AL10.alGetError() != AL10.AL_NO_ERROR) { + break; + } + } + System.out.println("Created " + numAuxSlots + " aux effect slots."); + + // Try to create 2 Effects + int numEffects = 0; + final int[] effects = new int[2]; + for (numEffects = 0; numEffects < 2; numEffects++) { + effects[numEffects] = EFX10.alGenEffects(); + if (AL10.alGetError() != AL10.AL_NO_ERROR) { + break; + } + } + System.out.println("Created " + numEffects + " effects."); + + // Set first Effect Type to Reverb and change Decay Time + AL10.alGetError(); + if (EFX10.alIsEffect(effects[0])) { + EFX10.alEffecti(effects[0], EFX10.AL_EFFECT_TYPE, EFX10.AL_EFFECT_REVERB); + if (AL10.alGetError() != AL10.AL_NO_ERROR) { + System.out.println("Reverb effect not supported."); + } else { + EFX10.alEffectf(effects[0], EFX10.AL_REVERB_DECAY_TIME, 5.0f); + System.out.println("Reverb effect created."); + } + } else { + throw new Exception("First effect not a valid effect."); + } + + // Set second Effect Type to Flanger and change Phase + AL10.alGetError(); + if (EFX10.alIsEffect(effects[1])) { + EFX10.alEffecti(effects[1], EFX10.AL_EFFECT_TYPE, EFX10.AL_EFFECT_FLANGER); + if (AL10.alGetError() != AL10.AL_NO_ERROR) { + System.out.println("Flanger effect not support."); + } else { + EFX10.alEffecti(effects[1], EFX10.AL_FLANGER_PHASE, 180); + System.out.println("Flanger effect created."); + } + } else { + throw new Exception("Second effect not a valid effect."); + } + + // Try to create a Filter + AL10.alGetError(); + final int filter = EFX10.alGenFilters(); + if (AL10.alGetError() != AL10.AL_NO_ERROR) { + throw new Exception("Failed to create filter."); + } + System.out.println("Generated a filter."); + if (EFX10.alIsFilter(filter)) { + // Set Filter type to Low-Pass and set parameters + EFX10.alFilteri(filter, EFX10.AL_FILTER_TYPE, EFX10.AL_FILTER_LOWPASS); + if (AL10.alGetError() != AL10.AL_NO_ERROR) { + System.out.println("Low pass filter not supported."); + } else { + EFX10.alFilterf(filter, EFX10.AL_LOWPASS_GAIN, 0.5f); + EFX10.alFilterf(filter, EFX10.AL_LOWPASS_GAINHF, 0.5f); + System.out.println("Low pass filter created."); + } + } + + // Attach Effect to Auxiliary Effect Slot + AL10.alGetError(); + EFX10.alAuxiliaryEffectSloti(auxEffectSlots[0], EFX10.AL_EFFECTSLOT_EFFECT, effects[0]); + if (AL10.alGetError() != AL10.AL_NO_ERROR) { + throw new Exception("Failed to attach effect to aux effect slot."); + } + System.out.println("Successfully loaded effect into effect slot."); + + // Configure Source Auxiliary Effect Slot Sends + final int source = AL10.alGenSources(); + // Set Source Send 0 to feed auxEffectSlots[0] without filtering + AL11.alSource3i(source, EFX10.AL_AUXILIARY_SEND_FILTER, auxEffectSlots[0], 0, + EFX10.AL_FILTER_NULL); + if (AL10.alGetError() != AL10.AL_NO_ERROR) { + throw new Exception("Failed to configure Source Send 0"); + } + System.out.println("Linked aux effect slot to soutce slot 0"); + // Set Source Send 1 to feed uiEffectSlot[1] with filter filter + AL11.alSource3i(source, EFX10.AL_AUXILIARY_SEND_FILTER, auxEffectSlots[1], 1, filter); + if (AL10.alGetError() != AL10.AL_NO_ERROR) { + // e.g. if only 1 send per source is available + throw new Exception("Failed to configure Source Send 1"); + } + System.out.println("Linked aux effect slot to soutce slot 1"); + // Disable Send 0 + AL11.alSource3i(source, EFX10.AL_AUXILIARY_SEND_FILTER, EFX10.AL_EFFECTSLOT_NULL, 0, + EFX10.AL_FILTER_NULL); + if (AL10.alGetError() != AL10.AL_NO_ERROR) { + throw new Exception("Failed to disable Source Send 0"); + } + System.out.println("Disabled source send 0"); + // Disable Send 1 + AL11.alSource3i(source, EFX10.AL_AUXILIARY_SEND_FILTER, EFX10.AL_EFFECTSLOT_NULL, 1, + EFX10.AL_FILTER_NULL); + if (AL10.alGetError() != AL10.AL_NO_ERROR) { + throw new Exception("Failed to disable Source Send 1"); + } + System.out.println("Disabled source send 1"); + + + // Filter 'source', a generated Source + AL10.alSourcei(source, EFX10.AL_DIRECT_FILTER, filter); + if (AL10.alGetError() == AL10.AL_NO_ERROR) { + { + System.out.println("Successfully applied a direct path filter"); + // Remove filter from 'source' + AL10.alSourcei(source, EFX10.AL_DIRECT_FILTER, EFX10.AL_FILTER_NULL); + if (AL10.alGetError() == AL10.AL_NO_ERROR) { + System.out.println("Successfully removed direct filter"); + } + } + // Filter the Source send 0 from 'source' to Auxiliary Effect Slot auxEffectSlot[0] + // using Filter uiFilter[0] + AL11.alSource3i(source, EFX10.AL_AUXILIARY_SEND_FILTER, auxEffectSlots[0], 0, filter); + if (AL10.alGetError() == AL10.AL_NO_ERROR) { + { + System.out.println("Successfully applied aux send filter"); + // Remove Filter from Source Auxiliary Send + AL11.alSource3i(source, EFX10.AL_AUXILIARY_SEND_FILTER, auxEffectSlots[0], 0, + EFX10.AL_FILTER_NULL); + if (AL10.alGetError() == AL10.AL_NO_ERROR) { + System.out.println("Successfully removed filter"); + } + } + } + } + + // Set Source Cone Outer Gain HF value + AL10.alSourcef(source, EFX10.AL_CONE_OUTER_GAINHF, 0.5f); + if (AL10.alGetError() == AL10.AL_NO_ERROR) { + System.out.println("Successfully set cone outside gain filter"); + } + + // Set distance units to be in feet + AL10.alListenerf(EFX10.AL_METERS_PER_UNIT, 0.3f); + if (AL10.alGetError() == AL10.AL_NO_ERROR) { + System.out.println("Successfully set distance units"); + } + + // Cleanup + final IntBuffer auxEffectSlotsBuf = (IntBuffer) BufferUtils.createIntBuffer( + auxEffectSlots.length).put(auxEffectSlots).rewind(); + EFX10.alDeleteAuxiliaryEffectSlots(auxEffectSlotsBuf); + final IntBuffer effectsBuf = (IntBuffer) BufferUtils.createIntBuffer( + effects.length).put(effects).rewind(); + EFX10.alDeleteEffects(effectsBuf); + EFX10.alDeleteFilters(filter); + AL.destroy(); + } + + /** + * Plays a sound with various effects applied to it. + */ + private static void playbackTest() throws Exception { + setupEfx(); + + // Create a source and buffer audio data + final int source = AL10.alGenSources(); + final int buffer = AL10.alGenBuffers(); + WaveData waveFile = WaveData.create(WaveData.class.getClassLoader().getResourceAsStream("Footsteps.wav")); + if (waveFile == null) { + System.out.println("Failed to load Footsteps.wav! Skipping playback test."); + AL.destroy(); + return; + } + AL10.alBufferData(buffer, waveFile.format, waveFile.data, waveFile.samplerate); + waveFile.dispose(); + AL10.alSourcei(source, AL10.AL_BUFFER, buffer); + AL10.alSourcei(source, AL10.AL_LOOPING, AL10.AL_TRUE); + + System.out.println("Playing sound unaffected by EFX ..."); + AL10.alSourcePlay(source); + Thread.sleep(7500); + + // Add reverb effect + final int effectSlot = EFX10.alGenAuxiliaryEffectSlots(); + final int reverbEffect = EFX10.alGenEffects(); + EFX10.alEffecti(reverbEffect, EFX10.AL_EFFECT_TYPE, EFX10.AL_EFFECT_REVERB); + EFX10.alEffectf(reverbEffect, EFX10.AL_REVERB_DECAY_TIME, 5.0f); + EFX10.alAuxiliaryEffectSloti(effectSlot, EFX10.AL_EFFECTSLOT_EFFECT, reverbEffect); + AL11.alSource3i(source, EFX10.AL_AUXILIARY_SEND_FILTER, effectSlot, 0, + EFX10.AL_FILTER_NULL); + + System.out.println("Playing sound with reverb ..."); + AL10.alSourcePlay(source); + Thread.sleep(7500); + + // Add low-pass filter directly to source + final int filter = EFX10.alGenFilters(); + EFX10.alFilteri(filter, EFX10.AL_FILTER_TYPE, EFX10.AL_FILTER_LOWPASS); + EFX10.alFilterf(filter, EFX10.AL_LOWPASS_GAIN, 0.5f); + EFX10.alFilterf(filter, EFX10.AL_LOWPASS_GAINHF, 0.5f); + AL10.alSourcei(source, EFX10.AL_DIRECT_FILTER, filter); + + System.out.println("Playing sound with reverb and direct low pass filter ..."); + AL10.alSourcePlay(source); + Thread.sleep(7500); + AL10.alSourcei(source, EFX10.AL_DIRECT_FILTER, EFX10.AL_FILTER_NULL); + + // Add low-pass filter to source send + //AL11.alSource3i(source, EFX10.AL_AUXILIARY_SEND_FILTER, effectSlot, 0, filter); + // + //System.out.println("Playing sound with reverb and aux send low pass filter ..."); + //AL10.alSourcePlay(source); + //Thread.sleep(7500); + + // Cleanup + AL11.alSource3i(source, EFX10.AL_AUXILIARY_SEND_FILTER, EFX10.AL_EFFECTSLOT_NULL, 0, + EFX10.AL_FILTER_NULL); + EFX10.alAuxiliaryEffectSloti(effectSlot, EFX10.AL_EFFECTSLOT_EFFECT, EFX10.AL_EFFECT_NULL); + EFX10.alDeleteEffects(reverbEffect); + EFX10.alDeleteFilters(filter); + + // Echo effect + final int echoEffect = EFX10.alGenEffects(); + EFX10.alEffecti(echoEffect, EFX10.AL_EFFECT_TYPE, EFX10.AL_EFFECT_ECHO); + //EFX10.alEffectf(echoEffect, EFX10.AL_ECHO_DELAY, 5.0f); + EFX10.alAuxiliaryEffectSloti(effectSlot, EFX10.AL_EFFECTSLOT_EFFECT, echoEffect); + AL11.alSource3i(source, EFX10.AL_AUXILIARY_SEND_FILTER, effectSlot, 0, + EFX10.AL_FILTER_NULL); + + System.out.println("Playing sound with echo effect ..."); + AL10.alSourcePlay(source); + Thread.sleep(7500); + + AL.destroy(); + } + + /** + * Checks OpenAL for every EFX 1.0 effect and filter and prints the result to the console. + */ + private static void efxUtilTest() throws Exception { + setupEfx(); + + System.out.println(); + System.out.println("Checking supported effects ..."); + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_NULL)) { + System.out.println("AL_EFFECT_NULL is supported."); + } else { + System.out.println("AL_EFFECT_NULL is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_EAXREVERB)) { + System.out.println("AL_EFFECT_EAXREVERB is supported."); + } else { + System.out.println("AL_EFFECT_EAXREVERB is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_REVERB)) { + System.out.println("AL_EFFECT_REVERB is supported."); + } else { + System.out.println("AL_EFFECT_REVERB is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_CHORUS)) { + System.out.println("AL_EFFECT_CHORUS is supported."); + } else { + System.out.println("AL_EFFECT_CHORUS is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_DISTORTION)) { + System.out.println("AL_EFFECT_DISTORTION is supported."); + } else { + System.out.println("AL_EFFECT_DISTORTION is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_ECHO)) { + System.out.println("AL_EFFECT_ECHO is supported."); + } else { + System.out.println("AL_EFFECT_ECHO is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_FLANGER)) { + System.out.println("AL_EFFECT_FLANGER is supported."); + } else { + System.out.println("AL_EFFECT_FLANGER is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_FREQUENCY_SHIFTER)) { + System.out.println("AL_EFFECT_FREQUENCY_SHIFTER is supported."); + } else { + System.out.println("AL_EFFECT_FREQUENCY_SHIFTER is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_VOCAL_MORPHER)) { + System.out.println("AL_EFFECT_VOCAL_MORPHER is supported."); + } else { + System.out.println("AL_EFFECT_VOCAL_MORPHER is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_PITCH_SHIFTER)) { + System.out.println("AL_EFFECT_PITCH_SHIFTER is supported."); + } else { + System.out.println("AL_EFFECT_PITCH_SHIFTER is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_RING_MODULATOR)) { + System.out.println("AL_EFFECT_RING_MODULATOR is supported."); + } else { + System.out.println("AL_EFFECT_RING_MODULATOR is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_AUTOWAH)) { + System.out.println("AL_EFFECT_AUTOWAH is supported."); + } else { + System.out.println("AL_EFFECT_AUTOWAH is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_COMPRESSOR)) { + System.out.println("AL_EFFECT_COMPRESSOR is supported."); + } else { + System.out.println("AL_EFFECT_COMPRESSOR is NOT supported."); + } + if (EFXUtil.isEffectSupported(EFX10.AL_EFFECT_EQUALIZER)) { + System.out.println("AL_EFFECT_EQUALIZER is supported."); + } else { + System.out.println("AL_EFFECT_EQUALIZER is NOT supported."); + } + + System.out.println(); + System.out.println("Checking supported filters ..."); + if (EFXUtil.isFilterSupported(EFX10.AL_FILTER_NULL)) { + System.out.println("AL_FILTER_NULL is supported."); + } else { + System.out.println("AL_FILTER_NULL is NOT supported."); + } + if (EFXUtil.isFilterSupported(EFX10.AL_FILTER_LOWPASS)) { + System.out.println("AL_FILTER_LOWPASS is supported."); + } else { + System.out.println("AL_FILTER_LOWPASS is NOT supported."); + } + if (EFXUtil.isFilterSupported(EFX10.AL_FILTER_HIGHPASS)) { + System.out.println("AL_FILTER_HIGHPASS is supported."); + } else { + System.out.println("AL_FILTER_HIGHPASS is NOT supported."); + } + if (EFXUtil.isFilterSupported(EFX10.AL_FILTER_BANDPASS)) { + System.out.println("AL_FILTER_BANDPASS is supported."); + } else { + System.out.println("AL_FILTER_BANDPASS is NOT supported."); + } + } +} diff --git a/src/java/org/lwjgl/test/openal/OpenALInfo.java b/src/java/org/lwjgl/test/openal/OpenALInfo.java index 20c919a..9a2ec72 100644 --- a/src/java/org/lwjgl/test/openal/OpenALInfo.java +++ b/src/java/org/lwjgl/test/openal/OpenALInfo.java @@ -32,6 +32,11 @@ package org.lwjgl.test.openal; import java.nio.IntBuffer; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; import org.lwjgl.BufferUtils; import org.lwjgl.LWJGLException; @@ -40,6 +45,8 @@ import org.lwjgl.openal.ALC10; import org.lwjgl.openal.ALC11; import org.lwjgl.openal.ALCdevice; +import org.lwjgl.openal.EFX10; +import org.lwjgl.openal.EFXUtil; /** * @@ -70,6 +77,7 @@ printALCInfo(); printALInfo(); + printEFXInfo(); checkForErrors(); @@ -94,7 +102,7 @@ device = ALC10.alcGetContextsDevice(ALC10.alcGetCurrentContext()); checkForErrors(); - System.out.println("Default device: " + ALC10.alcGetString(device, ALC10.ALC_DEFAULT_DEVICE_SPECIFIER)); + System.out.println("Default playback device: " + ALC10.alcGetString(device, ALC10.ALC_DEFAULT_DEVICE_SPECIFIER)); System.out.println("Default capture device: " + ALC10.alcGetString(device, ALC11.ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)); @@ -130,6 +138,70 @@ checkForErrors(); } + private void printEFXInfo() { + if(!EFXUtil.isEfxSupported()) { + System.out.println("EFX not available"); + return; + } + + ALCdevice device = AL.getDevice(); + IntBuffer major = BufferUtils.createIntBuffer(1); + IntBuffer minor = BufferUtils.createIntBuffer(1); + IntBuffer sends = BufferUtils.createIntBuffer(1); + ALC10.alcGetInteger(device, EFX10.ALC_EFX_MAJOR_VERSION, major); + ALC10.alcGetInteger(device, EFX10.ALC_EFX_MINOR_VERSION, minor); + if(ALC10.alcGetError(device) == ALC10.ALC_NO_ERROR) { + System.out.println("EFX version: " + major.get() + "." + minor.get()); + } + + ALC10.alcGetInteger(device, EFX10.ALC_MAX_AUXILIARY_SENDS, sends); + if(ALC10.alcGetError(device) == ALC10.ALC_NO_ERROR) { + System.out.println("Max auxiliary sends: " + sends.get()); + } + + System.out.println("Supported filters: "); + HashMap filters = new HashMap(); + filters.put("Low-pass", new Integer(EFX10.AL_FILTER_LOWPASS)); + filters.put("High-pass", new Integer(EFX10.AL_FILTER_HIGHPASS)); + filters.put("Band-pass", new Integer(EFX10.AL_FILTER_BANDPASS)); + + Set entries = filters.entrySet(); + for(Iterator i = entries.iterator(); i.hasNext();) { + Map.Entry entry = (Entry) i.next(); + int value = ((Integer)entry.getValue()).intValue(); + String key = (String) entry.getKey(); + if(EFXUtil.isFilterSupported(value)) { + System.out.println(" " + key); + } + } + + System.out.println("Supported effects: "); + HashMap effects = new HashMap(); + effects.put("EAX Reverb", new Integer(EFX10.AL_EFFECT_EAXREVERB)); + effects.put("Reverb", new Integer(EFX10.AL_EFFECT_REVERB)); + effects.put("Chorus", new Integer(EFX10.AL_EFFECT_CHORUS)); + effects.put("Distortion", new Integer(EFX10.AL_EFFECT_DISTORTION)); + effects.put("Echo", new Integer(EFX10.AL_EFFECT_ECHO)); + effects.put("Flanger", new Integer(EFX10.AL_EFFECT_FLANGER)); + effects.put("Frequency Shifter", new Integer(EFX10.AL_EFFECT_FREQUENCY_SHIFTER)); + effects.put("Vocal Morpher", new Integer(EFX10.AL_EFFECT_VOCAL_MORPHER)); + effects.put("Pitch Shifter", new Integer(EFX10.AL_EFFECT_PITCH_SHIFTER)); + effects.put("Ring Modulator", new Integer(EFX10.AL_EFFECT_RING_MODULATOR)); + effects.put("Autowah", new Integer(EFX10.AL_EFFECT_AUTOWAH)); + effects.put("Compressor", new Integer(EFX10.AL_EFFECT_COMPRESSOR)); + effects.put("Equalizer", new Integer(EFX10.AL_EFFECT_EQUALIZER)); + + entries = effects.entrySet(); + for(Iterator i = entries.iterator(); i.hasNext();) { + Map.Entry entry = (Entry) i.next(); + int value = ((Integer)entry.getValue()).intValue(); + String key = (String) entry.getKey(); + if(EFXUtil.isEffectSupported(value)) { + System.out.println(" " + key); + } + } + } + private void printDevices(int which, String kind) { String[] devices = ALC10.alcGetString(null, which).split("\0"); checkForErrors(); diff --git a/src/java/org/lwjgl/test/opengl/FullScreenWindowedTest.java b/src/java/org/lwjgl/test/opengl/FullScreenWindowedTest.java index d05ef3e..22892f0 100644 --- a/src/java/org/lwjgl/test/opengl/FullScreenWindowedTest.java +++ b/src/java/org/lwjgl/test/opengl/FullScreenWindowedTest.java @@ -33,6 +33,7 @@ import org.lwjgl.LWJGLException; import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.DisplayMode; import org.lwjgl.opengl.GL11; @@ -44,8 +45,8 @@ * Tests switching between windowed and fullscreen * * @author Brian Matzon - * @version $Revision: 3172 $ - * $Id: FullScreenWindowedTest.java 3172 2008-12-28 19:30:43Z elias_naur $ + * @version $Revision: 3365 $ + * $Id: FullScreenWindowedTest.java 3365 2010-07-04 18:24:53Z spasi $ */ public class FullScreenWindowedTest { /** Intended deiplay mode */ @@ -222,6 +223,8 @@ if (angleRotation > MAX_SPEED) { angleRotation = MAX_SPEED; } + + while ( Mouse.next() ); } /** * Cleans up the test diff --git a/src/java/org/lwjgl/test/opengl/VBOIndexTest.java b/src/java/org/lwjgl/test/opengl/VBOIndexTest.java index c563730..841e832 100644 --- a/src/java/org/lwjgl/test/opengl/VBOIndexTest.java +++ b/src/java/org/lwjgl/test/opengl/VBOIndexTest.java @@ -31,12 +31,12 @@ */ /** - * $Id: VBOIndexTest.java 2983 2008-04-07 18:36:09Z matzon $ + * $Id: VBOIndexTest.java 3344 2010-05-22 16:53:49Z spasi $ * * Simple java test program. * * @author elias_naur - * @version $Revision: 2983 $ + * @version $Revision: 3344 $ */ package org.lwjgl.test.opengl; @@ -179,6 +179,7 @@ mapped_indices_buffer); if ( new_mapped_buffer != mapped_indices_buffer ) mapped_indices_int_buffer = new_mapped_buffer.order(ByteOrder.nativeOrder()).asIntBuffer(); + mapped_indices_buffer = new_mapped_buffer; mapped_float_buffer.rewind(); vertices.rewind(); diff --git a/src/java/org/lwjgl/test/opengl/VersionTest.java b/src/java/org/lwjgl/test/opengl/VersionTest.java index b5172bc..6f4855c 100644 --- a/src/java/org/lwjgl/test/opengl/VersionTest.java +++ b/src/java/org/lwjgl/test/opengl/VersionTest.java @@ -29,13 +29,6 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * Created by LWJGL. - * User: spasi - * Date: 2009-04-04 - * Time: 21:20:24 pm - */ - package org.lwjgl.test.opengl; import org.lwjgl.LWJGLException; @@ -44,6 +37,11 @@ import java.util.StringTokenizer; import java.util.regex.Pattern; +/** + * Tests the ARB_create_context extension through the use of the ContextAttribs class. + * + * @author Spasi + */ public final class VersionTest { private VersionTest() { @@ -110,46 +108,105 @@ System.out.println("\n---------\n"); + System.out.println("Requested " + ca); + final String version = GL11.glGetString(GL11.GL_VERSION); - System.out.print("GL Version requested: " + majorInput + '.' + minorInput); - if ( ca.isProfileCore() ) - System.out.print(" - Core Profile"); - else if ( ca.isProfileCompatibility() ) - System.out.print(" - Compatibility Profile"); - System.out.println("\nGL Version returned : " + version); + boolean deprecated = false; + try { + GL11.glVertex3f(0.0f, 0.0f, 0.0f); + deprecated = true; + } catch (Throwable t) {} final StringTokenizer version_tokenizer = new StringTokenizer(version, ". "); int majorVersion = Integer.parseInt(version_tokenizer.nextToken()); int minorVersion = Integer.parseInt(version_tokenizer.nextToken()); - if ( majorVersion != majorInput || minorVersion != minorInput ) { - if ( majorInput == 1 && minorInput == 0 ) - System.out.println("\tThe maximum supported version has been returned. The driver is well-behaved. :)"); - else if ( majorInput < 3 && majorVersion < 3 ) - System.out.println("\tThe maximum supported version pre-3.0 has been returned. The driver is well-behaved. :)"); - else - System.out.println("\tThe requested version was not returned. The driver is buggy! :("); - } else - System.out.println("\tThe requested version was returned. :)"); - - if ( ca.isProfileCompatibility() && !GLContext.getCapabilities().GL_ARB_compatibility ) - System.out.println("\tThe driver does not support the Compatibility Profile."); - - System.out.println("\n---------\n"); - - System.out.println("Debug mode: " + ca.isDebug()); - System.out.println("Forward compatible mode: " + ca.isForwardCompatible()); - System.out.println("ARB_compatibility: " + GLContext.getCapabilities().GL_ARB_compatibility); - try { - GL11.glVertex3f(0.0f, 0.0f, 0.0f); - System.out.println("Deprecated functionality present: " + true); - } catch (Throwable t) { - System.out.println("Deprecated functionality present: " + false); - if ( GLContext.getCapabilities().GL_ARB_compatibility ) { - System.out.println("\tARB_compatibility is present, but LWJGL has enabled pseudo-forward compatible mode."); - } + final boolean compatibilityProfile; + final boolean coreProfile; + + if ( 3 < majorVersion || (majorVersion == 3 && 2 <= minorVersion) ) { + final int profileMask = GL11.glGetInteger(GL32.GL_CONTEXT_PROFILE_MASK); + + compatibilityProfile = (profileMask & GL32.GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0; + coreProfile = (profileMask & GL32.GL_CONTEXT_CORE_PROFILE_BIT) != 0; + } else { + compatibilityProfile = false; + coreProfile = false; + } + + System.out.println("\nGL_VERSION returned : " + version); + System.out.println("\tCore profile: " + coreProfile); + System.out.println("\tCompatibility profile: " + compatibilityProfile); + System.out.println("ARB_compatibility present: " + GLContext.getCapabilities().GL_ARB_compatibility); + System.out.println("Deprecated functionality present: " + deprecated); + if ( !deprecated && GLContext.getCapabilities().GL_ARB_compatibility ) + System.out.println("\tARB_compatibility is present, but LWJGL has enabled pseudo-forward compatible mode."); + + System.out.println("\n---------"); + + boolean success = false; + boolean check; + if ( majorInput < 3 || (majorInput == 3 && minorInput == 0) ) { + System.out.println("\nA version less than or equal to 3.0 is requested, the context\n" + + "returned may implement any of the following versions:"); + + System.out.println("\n1) Any version no less than that requested and no greater than 3.0."); + check = (majorInput < majorVersion || (majorInput == majorVersion && minorInput <= minorVersion)) // Satisfies requested version + && (majorVersion < 3 || (majorVersion == 3 && minorVersion == 0)); // 3.0 or earlier + System.out.println("\t" + check); + success |= check; + + System.out.println("\n2) Version 3.1, if the GL_ARB_compatibility extension is also implemented."); + check = majorVersion == 3 && minorVersion == 1 && GLContext.getCapabilities().GL_ARB_compatibility; + System.out.println("\t" + check); + success |= check; + + System.out.println("\n3) The compatibility profile of version 3.2 or greater."); + check = compatibilityProfile; // No need to check version, profiles are only available with 3.2+. + System.out.println("\t" + check); + success |= check; + + System.out.println("\nTEST " + (success ? "SUCCEEDED" : "FAILED")); + if ( !success && ca.isForwardCompatible() ) + System.out.println("\t(probably because the forward compatible flag was set)"); + } else if ( majorInput == 3 && minorInput == 1 ) { + System.out.println("\nVersion 3.1 is requested, the context returned may implement\n" + + "any of the following versions:"); + + System.out.println("\n1) Version 3.1. The GL_ARB_compatibility extension may or may not\n" + + "be implemented, as determined by the implementation."); + check = majorVersion == 3 && minorVersion == 1; + System.out.println("\t" + check); + success |= check; + + System.out.println("\n2) The core profile of version 3.2 or greater."); + check = coreProfile; // No need to check version, profiles are only available with 3.2+. + System.out.println("\t" + check); + success |= check; + + System.out.println("\nTEST " + (success ? "SUCCEEDED" : "FAILED")); + } else { + System.out.println("\nVersion 3.2 or greater is requested, the context returned may\n" + + "implement any of the following versions:"); + + System.out.println("\n1) The requested profile of the requested version."); + check = majorInput == majorVersion && minorInput == minorVersion + && (!ca.isProfileCompatibility() || compatibilityProfile) + && (!ca.isProfileCore() || coreProfile); + System.out.println("\t" + check); + success |= check; + + System.out.println("\n2) The requested profile of any later version, so long as no\n" + + "features have been removed from that later version and profile."); + check = majorInput < majorVersion || (majorInput == majorVersion && minorInput < minorVersion) + && (!ca.isProfileCompatibility() || compatibilityProfile) + && (!ca.isProfileCore() || coreProfile); + System.out.println("\t" + check); + success |= check; + + System.out.println("\nTEST " + (success ? "SUCCEEDED" : "FAILED")); } } @@ -174,12 +231,14 @@ private static void argsError(final String msg) { System.out.println("\nInvalid arguments error: " + msg); - System.out.println("\nUsage: VersionTest {, 'debug', 'fc'}:\n"); + System.out.println("\nUsage: VersionTest {'core'|'compatibility', , 'debug', 'fc'}:\n"); System.out.println("majorVersion\t- Major OpenGL version."); System.out.println("majorVersion\t- Minor OpenGL version."); + System.out.println("core\t- Sets the Core Profile bit (optional, requires 3.2+)."); + System.out.println("compatibility\t- Sets the Compatibility Profile bit (optional, requires 3.2+)."); System.out.println("layer\t- Layer plane (optional)."); System.out.println("debug\t- Enables debug mode (optional)."); - System.out.println("fc\t- Enables forward compatibility mode (optional)."); + System.out.println("fc\t- Enables forward compatibility mode (optional, requires 3.0+)."); cleanup(); System.exit(-1); @@ -193,4 +252,4 @@ System.exit(-1); } -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/test/opengl/awt/DemoBox.java b/src/java/org/lwjgl/test/opengl/awt/DemoBox.java index b0250ac..9604b4b 100644 --- a/src/java/org/lwjgl/test/opengl/awt/DemoBox.java +++ b/src/java/org/lwjgl/test/opengl/awt/DemoBox.java @@ -150,7 +150,7 @@ addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { - demoCanvas.destroy(); + demoCanvas.destroyCanvas(); dispose(); System.exit(0); } @@ -269,7 +269,7 @@ } } - public void destroy() { + public void destroyCanvas() { setActiveDemo(null); renderThread = null; } diff --git a/src/java/org/lwjgl/test/opengl/multithread/BackgroundLoadTest.java b/src/java/org/lwjgl/test/opengl/multithread/BackgroundLoadTest.java new file mode 100644 index 0000000..c068b60 --- /dev/null +++ b/src/java/org/lwjgl/test/opengl/multithread/BackgroundLoadTest.java @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.test.opengl.multithread; + +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.*; +import org.lwjgl.util.glu.GLU; +import org.lwjgl.util.glu.Sphere; + +import java.nio.FloatBuffer; + +/** + * A test of loading textures in a background thread. This can be achieved in 2 ways: + *
+ * a) A dummy Pbuffer is created and its context shares the rendering context.
+ * b) A SharedDrawable is used.
+ *
+ * When the test starts, there's no texture created and rendering is done with texturing disabled. + * 2 seconds later a "dummy" texture is created in the background thread and texturing is enabled. This dummy texture + * can by anything the developer wants to have as a placeholder while textures are being loaded. + * Finally, 5 seconds later the "true" texture is loaded and displayed. This texture will change every 5 seconds after + * that, until the test is terminated (ESC key). + * + * @author Spasi + */ +public final class BackgroundLoadTest { + + private static boolean run = true; + + private static BackgroundLoader backgroundLoader; + + private static Sphere sphere; + + private BackgroundLoadTest() { + } + + public static void main(String[] args) { + initialize(args); + + Util.checkGLError(); + + try { + backgroundLoader.start(); + } catch (LWJGLException e) { + kill("Failed to start background thread.", e); + } + + Util.checkGLError(); + + while ( run ) { + if ( !Display.isVisible() ) + Thread.yield(); + else { + handleIO(); + + GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); + + renderObject(); + + Util.checkGLError(); + + // Restore camera position. + GL11.glPopMatrix(); + GL11.glPushMatrix(); + } + + Display.update(); + + if ( Display.isCloseRequested() ) + break; + } + + cleanup(); + System.exit(0); + } + + private static void initialize(String[] args) { + if ( args.length != 1 ) + argsError(); + + DisplayMode displayMode = null; + + try { + DisplayMode[] modes = Display.getAvailableDisplayModes(); + + displayMode = chooseMode(modes, 1024, 768); + if ( displayMode == null ) + displayMode = chooseMode(modes, 800, 600); + if ( displayMode == null ) + displayMode = chooseMode(modes, 640, 480); + if ( displayMode == null ) + kill("Failed to set an appropriate display mode."); + + System.out.println("Setting display mode to: " + displayMode); + Display.setDisplayMode(displayMode); + Display.setTitle("Background Loading Test"); + Display.create(new PixelFormat(8, 24, 0)); + } catch (LWJGLException e) { + kill(e.getMessage()); + } + + GL11.glViewport(0, 0, displayMode.getWidth(), displayMode.getHeight()); + + GL11.glMatrixMode(GL11.GL_PROJECTION); + GL11.glLoadIdentity(); + GLU.gluPerspective(45, displayMode.getWidth() / (float)displayMode.getHeight(), 1.0f, 10.0f); + + GL11.glMatrixMode(GL11.GL_MODELVIEW); + GL11.glLoadIdentity(); + + // Setup camera position. + GL11.glTranslatef(0.0f, 0.0f, -4.0f); + GL11.glRotatef(90.0f, 1.0f, 0.0f, 0.0f); + GL11.glPushMatrix(); + + GL11.glClearDepth(1.0f); + GL11.glDepthFunc(GL11.GL_LEQUAL); + + GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST); + + GL11.glFrontFace(GL11.GL_CCW); + GL11.glPolygonMode(GL11.GL_FRONT, GL11.GL_FILL); + + GL11.glCullFace(GL11.GL_BACK); + GL11.glEnable(GL11.GL_CULL_FACE); + + GL11.glAlphaFunc(GL11.GL_GREATER, 0.0f); + GL11.glEnable(GL11.GL_ALPHA_TEST); + + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL11.GL_BLEND); + + GL11.glShadeModel(GL11.GL_SMOOTH); + + final FloatBuffer vectorBuffer = BufferUtils.createFloatBuffer(4); + + vectorBuffer.clear(); + vectorBuffer.put(0, 1.0f).put(1, 1.0f).put(2, 1.0f).put(3, 1.0f); + GL11.glLight(GL11.GL_LIGHT0, GL11.GL_DIFFUSE, vectorBuffer); + + vectorBuffer.put(0, 1.0f).put(1, 1.0f).put(2, 1.0f).put(3, 1.0f); + GL11.glLight(GL11.GL_LIGHT0, GL11.GL_AMBIENT, vectorBuffer); + + vectorBuffer.put(0, 1.0f).put(1, 1.0f).put(2, 0.5f).put(3, 1.0f); + GL11.glLight(GL11.GL_LIGHT0, GL11.GL_SPECULAR, vectorBuffer); + + vectorBuffer.put(0, -1.0f / 3.0f).put(1, 1.0f / 3.0f).put(2, 1.0f / 3.0f).put(3, 0.0f); // Infinite + GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, vectorBuffer); + + vectorBuffer.put(0, 0.2f).put(1, 0.2f).put(2, 0.2f).put(3, 1.0f); + GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, vectorBuffer); + + GL11.glEnable(GL11.GL_LIGHT0); + GL11.glEnable(GL11.GL_LIGHTING); + + sphere = new Sphere(); + + if ( "PB".equalsIgnoreCase(args[0]) ) { + backgroundLoader = new BackgroundLoader() { + Drawable getDrawable() throws LWJGLException { + return new Pbuffer(2, 2, new PixelFormat(8, 24, 0), Display.getDrawable()); + } + }; + } else if ( "SD".equalsIgnoreCase(args[0]) ) { + backgroundLoader = new BackgroundLoader() { + Drawable getDrawable() throws LWJGLException { + return new SharedDrawable(Display.getDrawable()); + } + }; + } else { + argsError(); + } + } + + private static void handleIO() { + if ( Keyboard.getNumKeyboardEvents() != 0 ) { + while ( Keyboard.next() ) { + if ( Keyboard.getEventKeyState() ) + continue; + + switch ( Keyboard.getEventKey() ) { + case Keyboard.KEY_ESCAPE: + run = false; + break; + } + } + } + + while ( Mouse.next() ) ; + } + + static void renderObject() { + GL11.glColor3f(1.0f, 1.0f, 1.0f); + + int texID = backgroundLoader.getTexID(); + if ( texID == 0 ) { + sphere.setTextureFlag(false); + GL11.glDisable(GL11.GL_TEXTURE_2D); + } else { + sphere.setTextureFlag(true); + GL11.glEnable(GL11.GL_TEXTURE_2D); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID); + } + + sphere.draw(1.0f, 32, 32); + + if ( texID != 0 ) { // Unbind so we can update from the background thread. + GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); + GL11.glDisable(GL11.GL_TEXTURE_2D); + } + } + + private static DisplayMode chooseMode(DisplayMode[] modes, int width, int height) { + DisplayMode bestMode = null; + + for ( int i = 0; i < modes.length; i++ ) { + DisplayMode mode = modes[i]; + if ( mode.getWidth() == width && mode.getHeight() == height && mode.getFrequency() <= 85 ) { + if ( bestMode == null || (mode.getBitsPerPixel() >= bestMode.getBitsPerPixel() && mode.getFrequency() > bestMode.getFrequency()) ) + bestMode = mode; + } + } + + return bestMode; + } + + private static void cleanup() { + backgroundLoader.cleanup(); + + Thread.yield(); // Let background thread finish. + + if ( Display.isCreated() ) + Display.destroy(); + } + + private static void argsError() { + System.out.println("\nInvalid program arguments."); + System.out.println("\nUsage: BackgroundLoadTest , where argument can be one of the following:\n"); + System.out.println("PB\t- Use a Pbuffer context for the background thread."); + System.out.println("SD\t- Use a SharedDrawable context for the background thread."); + + cleanup(); + System.exit(-1); + } + + static void kill(String reason) { + System.out.println("The BackgroundLoadTest program was terminated because an error occured.\n"); + System.out.println("Reason: " + (reason == null ? "Unknown" : reason)); + + cleanup(); + System.exit(-1); + } + + static void kill(String reason, Throwable t) { + System.out.println("The BackgroundLoadTest program was terminated because an exception occured.\n"); + System.out.println("Reason: " + (reason == null ? "Unknown" : reason)); + + System.out.println("Exception message: " + t.getMessage()); + + cleanup(); + System.exit(-1); + } + +} \ No newline at end of file diff --git a/src/java/org/lwjgl/test/opengl/multithread/BackgroundLoader.java b/src/java/org/lwjgl/test/opengl/multithread/BackgroundLoader.java new file mode 100644 index 0000000..475e336 --- /dev/null +++ b/src/java/org/lwjgl/test/opengl/multithread/BackgroundLoader.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Created by LWJGL. + * User: spasi + * Date: 2004-03-30 + * Time: 8:41:42 pm + */ +package org.lwjgl.test.opengl.multithread; + +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.opengl.Drawable; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.Color; +import org.lwjgl.util.ReadableColor; + +import java.nio.ByteBuffer; + +abstract class BackgroundLoader { + + private static final int WIDTH = 32; + private static final int HEIGHT = 32; + + private static final Object lock = new Object(); + + private Drawable drawable; + + private boolean running; + + private ByteBuffer texture; + private int texID; + + protected BackgroundLoader() { + running = true; + texture = BufferUtils.createByteBuffer(WIDTH * HEIGHT * 3); + } + + abstract Drawable getDrawable() throws LWJGLException; + + void cleanup() { + running = false; + } + + void start() throws LWJGLException { + new Thread(new Runnable() { + public void run() { + System.out.println("-- Background Thread started --"); + + System.out.println("** Sleeping, no texture created yet **"); + + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + try { + drawable = getDrawable(); + drawable.makeCurrent(); + } catch (LWJGLException e) { + throw new RuntimeException(e); + } + + System.out.println("** Drawable created **"); + + synchronized ( lock ) { + // Create a "dummy" texture while we wait for texture IO + createCheckerTexture(Color.RED, Color.WHITE, 2); + + texID = GL11.glGenTextures(); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID); + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, WIDTH, HEIGHT, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, texture); + + GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); + GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); + + GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); + } + + System.out.println("** Dummy texture created **"); + + long lastTextureCreated = System.currentTimeMillis(); // Delay first texture creation + int count = 0; + while ( running ) { + long time = System.currentTimeMillis(); + if ( time - lastTextureCreated < 5000 ) { // Update the texture every 5 seconds + try { + Thread.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + continue; + } + + // Create the "true" texture + if ( count % 2 == 0 ) + createGradientTexture(Color.RED, Color.BLUE); + else + createGradientTexture(Color.GREEN, Color.YELLOW); + + GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID); + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, WIDTH, HEIGHT, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, texture); + + GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); + GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); + + GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); + + System.out.println("** Created new gradient texture **"); + + lastTextureCreated = System.currentTimeMillis(); + count++; + } + + drawable.destroy(); + + System.out.println("-- Background Thread finished --"); + } + }).start(); + } + + int getTexID() { + synchronized ( lock ) { + return texID; + } + } + + private void createCheckerTexture(final ReadableColor a, final ReadableColor b, final int size) { + int i = 0; + for ( int y = 0; y < HEIGHT; y++ ) { + for ( int x = 0; x < WIDTH; x++ ) { + ReadableColor c = (x / size) % 2 == 0 ? ((y / size) % 2 == 0 ? a : b) : ((y / size) % 2 == 0 ? b : a); + texture.put(i + 0, c.getRedByte()); + texture.put(i + 1, c.getGreenByte()); + texture.put(i + 2, c.getBlueByte()); + i += 3; + } + } + } + + private void createGradientTexture(final ReadableColor a, final ReadableColor b) { + float l = 0.0f; + int i = 0; + for ( int y = 0; y < HEIGHT; y++ ) { + for ( int x = 0; x < WIDTH; x++ ) { + texture.put(i + 0, lerp(a.getRed(), b.getRed(), l)); + texture.put(i + 1, lerp(a.getGreen(), b.getGreen(), l)); + texture.put(i + 2, lerp(a.getBlue(), b.getBlue(), l)); + i += 3; + } + l += (1.0f / (HEIGHT - 1)); + } + } + + private static byte lerp(final int a, final int b, final float l) { + return (byte)Math.round(((1.0f - l) * a + l * b)); + } + +} \ No newline at end of file diff --git a/src/java/org/lwjgl/util/WaveData.java b/src/java/org/lwjgl/util/WaveData.java index d6928e7..d1389aa 100644 --- a/src/java/org/lwjgl/util/WaveData.java +++ b/src/java/org/lwjgl/util/WaveData.java @@ -51,8 +51,8 @@ * Utitlity class for loading wavefiles. * * @author Brian Matzon - * @version $Revision: 3274 $ - * $Id: WaveData.java 3274 2010-02-20 10:43:22Z matzon $ + * @version $Revision: 3336 $ + * $Id: WaveData.java 3336 2010-04-26 21:52:59Z matzon $ */ public class WaveData { /** actual wave data */ @@ -108,7 +108,7 @@ * @return WaveData containing data, or null if a failure occured */ public static WaveData create(String path) { - return create(WaveData.class.getClassLoader().getResource(path)); + return create(Thread.currentThread().getContextClassLoader().getResource(path)); } /** diff --git a/src/java/org/lwjgl/util/applet/AppletLoader.java b/src/java/org/lwjgl/util/applet/AppletLoader.java index d9778b8..88b6b55 100644 --- a/src/java/org/lwjgl/util/applet/AppletLoader.java +++ b/src/java/org/lwjgl/util/applet/AppletLoader.java @@ -39,6 +39,7 @@ import java.awt.Graphics; import java.awt.Image; import java.awt.MediaTracker; +import java.awt.image.ImageObserver; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; @@ -47,6 +48,8 @@ import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; @@ -68,6 +71,7 @@ import java.security.SecureClassLoader; import java.security.cert.Certificate; import java.util.Enumeration; +import java.util.HashMap; import java.util.StringTokenizer; import java.util.Vector; import java.util.jar.JarEntry; @@ -106,11 +110,17 @@ *

    *
  • al_version - [int or float] Version of deployment. If this is specified, the jars will be cached and * reused if the version matches. If version doesn't match all of the files are reloaded.
  • - *
  • al_bgcolor - [String] Hex formated color to use as background. Default: ffffff.
  • - *
  • al_fgcolor - [String] Hex formated color to use as foreground. Default: 000000.
  • - *
  • al_errorcolor - [String] Hex formated color to use as foreground color on error. Default: ff0000.
  • + *
  • al_cache - [boolean] Whether to use cache system. Default: true.
  • *
  • al_debug - [boolean] Whether to enable debug mode. Default: false.
  • *
  • al_prepend_host - [boolean] Whether to limit caching to this domain, disable if your applet is hosted on multple domains and needs to share the cache. Default: true.
  • + *
      + *
    • al_windows64 - [String] If specified it will be used instead of al_windows on 64bit windows systems.
    • + *
    • al_windows32 - [String] If specifed it will be used instead of al_windows on 32bit windows systems.
    • + *
    • al_linux64 - [String] If specifed it will be used instead of al_linux on 64bit linux systems.
    • + *
    • al_linux32 - [String] If specifed it will be used instead of al_linux on 32bit linux systems.
    • + *
        + *
      • boxbgcolor - [String] any String AWT color ("red", "blue", etc), RGB (0-255) or hex formated color (#RRGGBB) to use as background. Default: #ffffff.
      • + *
      • boxfgcolor - [String] any String AWT color ("red", "blue", etc), RGB (0-255) or hex formated color (#RRGGBB) to use as foreground. Default: #000000.
      • *
      *

      * @author kappaOne @@ -166,19 +176,19 @@ protected int totalSizeExtract; /** logo to be shown while loading */ - protected Image logo; + protected Image logo, logoBuffer; /** progressbar to render while loading */ - protected Image progressbar; + protected Image progressbar, progressbarBuffer; /** offscreen image used */ protected Image offscreen; + /** set to true while painting is done */ + protected boolean painting; + /** background color of applet */ protected Color bgColor = Color.white; - - /** Color to write errors in */ - protected Color errorColor = Color.red; /** color to write foreground in */ protected Color fgColor = Color.black; @@ -209,6 +219,15 @@ /** whether to prepend host to cache path */ protected boolean prependHost; + + /** Used to store file names with lastModified time */ + protected HashMap filesLastModified; + + /** Sizes of files to download */ + protected int[] fileSizes; + + /** whether to use caching system, only download files that have changed */ + protected boolean cacheEnabled; /** String to display as a subtask */ protected String subtaskMessage = ""; @@ -252,7 +271,10 @@ return; } } - + + // whether to use cache system + cacheEnabled = getBooleanParameter("al_cache", true); + // whether to run in debug mode debugMode = getBooleanParameter("al_debug", false); @@ -260,11 +282,9 @@ prependHost = getBooleanParameter("al_prepend_host", true); // get colors of applet - bgColor = getColor("al_bgcolor", Color.white); + bgColor = getColor("boxbgcolor", Color.white); setBackground(bgColor); - - fgColor = getColor("al_fgcolor", Color.black); - errorColor = getColor("al_errorcolor", Color.red); + fgColor = getColor("boxfgcolor", Color.black); // load logos logo = getImage(getParameter("al_logo")); @@ -339,7 +359,6 @@ if (lwjglApplet != null) { lwjglApplet.stop(); } - super.stop(); } /* @@ -353,7 +372,8 @@ progressbar = null; logo = null; - super.destroy(); + logoBuffer = null; + progressbarBuffer = null; } /** @@ -390,22 +410,34 @@ // create offscreen if missing if (offscreen == null) { offscreen = createImage(getWidth(), getHeight()); + + // create buffers for animated gifs + logoBuffer = createImage(logo.getWidth(null), logo.getHeight(null)); + progressbarBuffer = createImage(logo.getWidth(null), logo.getHeight(null)); + + // add image observer, it will notify when next animated gif frame is ready + offscreen.getGraphics().drawImage(logo, 0, 0, this); + offscreen.getGraphics().drawImage(progressbar, 0, 0, this); + + // in case image is not animated fill image buffers once + imageUpdate(logo, ImageObserver.FRAMEBITS, 0, 0, 0, 0); + imageUpdate(progressbar, ImageObserver.FRAMEBITS, 0, 0, 0, 0); } // draw everything onto an image before drawing to avoid flicker Graphics og = offscreen.getGraphics(); FontMetrics fm = og.getFontMetrics(); - // set background color + // clear background color og.setColor(bgColor); - og.fillRect(0, 0, getWidth(), getHeight()); + og.fillRect(0, 0, offscreen.getWidth(null), offscreen.getHeight(null)); // get logo position so its in the middle of applet int x = 0, y = 0; if(logo != null && !fatalError) { - x = (getWidth() - logo.getWidth(this)) / 2; - y = (getHeight() - logo.getHeight(this)) / 2; + x = (offscreen.getWidth(null) - logo.getWidth(null)) / 2; + y = (offscreen.getHeight(null) - logo.getHeight(null)) / 2; } og.setColor(fgColor); @@ -421,41 +453,79 @@ for(int i=0; i 0) { - messageX = (getWidth() - fm.stringWidth(subtaskMessage)) / 2; + messageX = (offscreen.getWidth(null) - fm.stringWidth(subtaskMessage)) / 2; og.drawString(subtaskMessage, messageX, messageY+20); } // draw loading bar, clipping it depending on percentage done - int barSize = (progressbar.getWidth(this) * percentage) / 100; - og.clipRect(0, 0, x + barSize, getHeight()); - og.drawImage(progressbar, x, y, null); + int barSize = (progressbarBuffer.getWidth(null) * percentage) / 100; + og.clipRect(0, 0, x + barSize, offscreen.getHeight(null)); + og.drawImage(progressbarBuffer, x, y, this); + + painting = false; } og.dispose(); - - // finally draw it all - g.drawImage(offscreen, 0, 0, null); - } + + // finally draw it all centred + g.drawImage(offscreen, (getWidth() - offscreen.getWidth(null))/2, (getHeight() - offscreen.getHeight(null))/2, null); + } + + /** + * When an animated gif frame is ready to be drawn the ImageObserver + * will call this method. + * + * The Image frame is copied into a buffer, which is then drawn. + * This is done to prevent image tearing on gif animations. + */ + public boolean imageUpdate(Image img, int flag, int x, int y, int width, int height) { + + // if image frame is ready to be drawn and is currently not being painted + if (flag == ImageObserver.FRAMEBITS && !painting) { + Image buffer; + + // select which buffer to fill + if (img == logo) buffer = logoBuffer; + else buffer = progressbarBuffer; + + Graphics g = buffer.getGraphics(); + + // clear background on buffer + g.setColor(bgColor); + g.fillRect(0, 0, buffer.getWidth(null), buffer.getHeight(null)); + + // buffer background is cleared, so draw logo under progressbar + if (img == progressbar) g.drawImage(logoBuffer, 0, 0, null); + + g.drawImage(img, 0, 0, this); + g.dispose(); + + repaint(); + } + + return true; + } /** * @return string describing the state of the loader @@ -467,7 +537,7 @@ case STATE_DETERMINING_PACKAGES: return "Determining packages to load"; case STATE_CHECKING_CACHE: - return "Checking cache for existing files"; + return "Calculating download size"; case STATE_DOWNLOADING: return "Downloading packages"; case STATE_EXTRACTING_PACKAGES: @@ -534,9 +604,31 @@ String nativeJar = null; if (osName.startsWith("Win")) { - nativeJar = getParameter("al_windows"); + + // check if arch specific natives have been specified + if (System.getProperty("os.arch").endsWith("64")) { + nativeJar = getParameter("al_windows64"); + } else { + nativeJar = getParameter("al_windows32"); + } + + if (nativeJar == null) { + nativeJar = getParameter("al_windows"); + } + } else if (osName.startsWith("Linux")) { - nativeJar = getParameter("al_linux"); + + // check if arch specific natives have been specified + if (System.getProperty("os.arch").endsWith("64")) { + nativeJar = getParameter("al_linux64"); + } else { + nativeJar = getParameter("al_linux32"); + } + + if (nativeJar == null) { + nativeJar = getParameter("al_linux"); + } + } else if (osName.startsWith("Mac")) { nativeJar = getParameter("al_mac"); } else if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) { @@ -598,10 +690,11 @@ if (!dir.exists()) { dir.mkdirs(); } - dir = new File(dir, "version"); - - // if applet already available don't download anything - boolean cacheAvailable = false; + + File versionFile = new File(dir, "version"); + + // if specified applet version already available don't download anything + boolean versionAvailable = false; // version of applet String version = getParameter("al_version"); @@ -613,10 +706,10 @@ latestVersion = Float.parseFloat(version); // if version file exists - if (dir.exists()) { + if (versionFile.exists()) { // compare to new version - if (latestVersion <= readVersionFile(dir)) { - cacheAvailable = true; + if (latestVersion <= readVersionFile(versionFile)) { + versionAvailable = true; percentage = 90; if(debugMode) { @@ -628,9 +721,12 @@ } // if jars not available or need updating download them - if (!cacheAvailable) { + if (!versionAvailable) { + // get jars file sizes and check cache + getJarInfo(dir); // 5-15% + // downloads jars from the server - downloadJars(path); // 10-55% + downloadJars(path); // 15-55% // Extract Pack and LZMA files extractJars(path); // 55-65% @@ -638,11 +734,14 @@ // Extracts Native Files extractNatives(path); // 65-85% - // add version information once jars downloaded successfully + // save version information once jars downloaded successfully if (version != null) { percentage = 90; writeVersionFile(dir, latestVersion); } + + // save file names with last modified info once downloaded successfully + writeCacheFile(new File(dir, "cache"), filesLastModified); } // add the downloaded jars and natives to classpath @@ -686,6 +785,33 @@ protected void writeVersionFile(File file, float version) throws Exception { DataOutputStream dos = new DataOutputStream(new FileOutputStream(file)); dos.writeFloat(version); + dos.close(); + } + + /** + * read the current cache file + * + * @param file the file to read + * @return the hashmap containing the files names and lastModified times + * @throws Exception if it fails to read hashmap + */ + protected HashMap readCacheFile(File file) throws Exception { + ObjectInputStream dis = new ObjectInputStream(new FileInputStream(file)); + HashMap hashMap = (HashMap)dis.readObject(); + dis.close(); + return hashMap; + } + + /** + * write out cache file of applet + * + * @param file the file to write out to + * @param filesLastModified the hashmap containing files names and lastModified times + * @throws Exception if it fails to write file + */ + protected void writeCacheFile(File file, HashMap filesLastModified) throws Exception { + ObjectOutputStream dos = new ObjectOutputStream(new FileOutputStream(file)); + dos.writeObject(filesLastModified); dos.close(); } @@ -765,7 +891,7 @@ * Due to the way applets on plugin1 work, one jvm must * be used for all applets. We need to use multiple * classloaders in the same jvm due to LWJGL's static - * nature. I order to solver this we simply remove the + * nature. I order to solve this we simply remove the * natives from a previous classloader allowing a new * classloader to use those natives in the same jvm. * @@ -830,22 +956,32 @@ state = STATE_START_REAL_APPLET; lwjglApplet.start(); } - - /** - * Will download the jars from the server using the list of urls - * in urlList, while at the same time updating progress bar - * - * @param path location of the directory to save to - * @throws Exception if download fails - */ - protected void downloadJars(String path) throws Exception { - - state = STATE_DOWNLOADING; - + + /** + * This method will get the files sizes of the files to download. + * It wil further get the lastModified time of files + * and save it in a hashmap, if cache is enabled it will mark + * those files that have not changed since last download to not + * redownloaded. + * + * @param dir - location to read cache file from + * @throws Exception - if fails to get infomation + */ + protected void getJarInfo(File dir) throws Exception { + + filesLastModified = new HashMap(); + + // store file sizes and mark which files not to download + fileSizes = new int[urlList.length]; + URLConnection urlconnection; - // store file sizes, used for download verification - int[] fileSizes = new int[urlList.length]; + File cacheFile = new File(dir, "cache"); + + // if cache file exists, load it + if (cacheFile.exists()) { + filesLastModified = readCacheFile(cacheFile); + } // calculate total size of jars to download for (int i = 0; i < urlList.length; i++) { @@ -854,15 +990,56 @@ if (urlconnection instanceof HttpURLConnection) { ((HttpURLConnection) urlconnection).setRequestMethod("HEAD"); } + fileSizes[i] = urlconnection.getContentLength(); - totalSizeDownload += fileSizes[i]; - } - - int initialPercentage = percentage = 10; + + long lastModified = urlconnection.getLastModified(); + String fileName = getFileName(urlList[i]); + + + if (cacheEnabled && lastModified != 0 && + filesLastModified.containsKey(fileName)) { + long savedLastModified = ((Long)filesLastModified.get(fileName)).longValue(); + + // if lastModifed time is the same, don't redownload + if (savedLastModified == lastModified) { + fileSizes[i] = -2; // mark it to not redownload + } + } + + if (fileSizes[i] >= 0) { + totalSizeDownload += fileSizes[i]; + } + + // put key and value in the hashmap + filesLastModified.put(fileName, new Long(lastModified)); + + // update progress bar + percentage = 5 + (int)(10 * i/(float)urlList.length); + } + } + + /** + * Will download the jars from the server using the list of urls + * in urlList, while at the same time updating progress bar + * + * @param path location of the directory to save to + * @throws Exception if download fails + */ + protected void downloadJars(String path) throws Exception { + + state = STATE_DOWNLOADING; + + URLConnection urlconnection; + + int initialPercentage = percentage = 15; // download each jar byte buffer[] = new byte[65536]; for (int i = 0; i < urlList.length; i++) { + + // skip file if marked as -2 (already downloaded and not changed) + if (fileSizes[i] == -2) continue; int unsuccessfulAttempts = 0; int maxUnsuccessfulAttempts = 3; @@ -909,7 +1086,7 @@ // round to two decimal places downloadSpeed = ((int)(downloadSpeed*100))/100f; // set current speed message - downloadSpeedMessage = " @ " + downloadSpeed + " KB/sec"; + downloadSpeedMessage = " - " + downloadSpeed + " KB/sec"; // reset downloaded amount downloadedAmount = 0; // reset start time @@ -1067,6 +1244,10 @@ float increment = (float) 10.0 / urlList.length; // extract all lzma and pack.lzma files for (int i = 0; i < urlList.length; i++) { + + // if file has not changed, skip it + if (fileSizes[i] == -2) continue; + percentage = 55 + (int) (increment * (i+1)); String filename = getFileName(urlList[i]); @@ -1102,6 +1283,11 @@ */ protected void extractNatives(String path) throws Exception { + // if no new native jar was downloaded, no extracting needed + if (fileSizes[fileSizes.length-1] == -2) { + return; + } + state = STATE_EXTRACTING_PACKAGES; int initialPercentage = percentage; @@ -1293,12 +1479,39 @@ * @param defaultColor Default color to use if no color to load * @return Color to use */ - protected Color getColor(String color, Color defaultColor) { - String param_color = getParameter(color); - if (param_color != null) { - return new Color(Integer.parseInt(param_color, 16)); - } - return defaultColor; + protected Color getColor(String param, Color defaultColor) { + String color = getParameter(param); + + if (color == null) return defaultColor; + + // Check if RGB format + if (color.indexOf(",") != -1) { + StringTokenizer st = new StringTokenizer(color, ","); + + // We've got three components for the color + try { + return new Color(Integer.parseInt(st.nextToken().trim()), + Integer.parseInt(st.nextToken().trim()), + Integer.parseInt(st.nextToken().trim())); + } catch (Exception e) { + // failed to parse + return defaultColor; + } + } + + // Check & decode if the color is in hexadecimal color format (i.e. #808000) + try { + return Color.decode(color); + } catch (NumberFormatException e) { + // ignore exception + } + + // Get the color by name if it exists + try { + return (Color)Color.class.getField(color).get(null); + } catch (Exception e) { + return defaultColor; + } } /** @@ -1322,7 +1535,7 @@ */ protected void fatalErrorOccured(String error, Exception e) { fatalError = true; - fatalErrorDescription = "Fatal error occured (" + state + "): " + error; + fatalErrorDescription = "This occurred while '" + getDescriptionForState() + "'"; System.out.println(fatalErrorDescription); if(e != null) { System.out.println(generateStacktrace(e)); diff --git a/src/java/org/lwjgl/util/generator/Alias.java b/src/java/org/lwjgl/util/generator/Alias.java new file mode 100644 index 0000000..c6776be --- /dev/null +++ b/src/java/org/lwjgl/util/generator/Alias.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.generator; + +/** + * This annotation can be used for extensions that have aliases + * with the exact same functionality. + *

      + * This is currently only implemented for context-specific functionality. + * + * @author Spasi + */ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +public @interface Alias { + + /** The aliased extension name. */ + String value(); + + /** The function name postfix for the aliased version. (optional) */ + String postfix() default ""; + +} \ No newline at end of file diff --git a/src/java/org/lwjgl/util/generator/AutoSize.java b/src/java/org/lwjgl/util/generator/AutoSize.java index 8ea4716..726abd2 100644 --- a/src/java/org/lwjgl/util/generator/AutoSize.java +++ b/src/java/org/lwjgl/util/generator/AutoSize.java @@ -37,8 +37,8 @@ * according to the remaining() of a Buffer parameter. * * @author elias_naur - * @version $Revision: 2983 $ - * $Id: AutoSize.java 2983 2008-04-07 18:36:09Z matzon $ + * @version $Revision: 3355 $ + * $Id: AutoSize.java 3355 2010-05-27 22:56:29Z spasi $ */ import java.lang.annotation.Target; @@ -49,4 +49,5 @@ public @interface AutoSize { String value(); // The name of the Buffer parameter String expression() default ""; // This value is added after the argument + boolean canBeNull() default false; // When this is true and the Buffer parameter is null, 0 will be used. } diff --git a/src/java/org/lwjgl/util/generator/ContextCapabilitiesGenerator.java b/src/java/org/lwjgl/util/generator/ContextCapabilitiesGenerator.java index 4feba92..d762aad 100644 --- a/src/java/org/lwjgl/util/generator/ContextCapabilitiesGenerator.java +++ b/src/java/org/lwjgl/util/generator/ContextCapabilitiesGenerator.java @@ -46,24 +46,23 @@ * Generator visitor for the context capabilities generator tool * * @author elias_naur - * @version $Revision: 3316 $ - * $Id: ContextCapabilitiesGenerator.java 3316 2010-04-09 23:57:40Z spasi $ + * @version $Revision: 3355 $ + * $Id: ContextCapabilitiesGenerator.java 3355 2010-05-27 22:56:29Z spasi $ */ public class ContextCapabilitiesGenerator { - private final static String STUBS_LOADED_NAME = "loaded_stubs"; - private final static String ALL_INIT_METHOD_NAME = "initAllStubs"; - private final static String POINTER_INITIALIZER_POSTFIX = "_initNativeFunctionAddresses"; - private final static String CACHED_EXTS_VAR_NAME = "supported_extensions"; - private final static String PROFILE_MASK_VAR_NAME = "profileMask"; - private final static String EXTENSION_PREFIX = "GL_"; - private final static String CORE_PREFIX = "Open"; + private static final String STUBS_LOADED_NAME = "loaded_stubs"; + private static final String ALL_INIT_METHOD_NAME = "initAllStubs"; + private static final String POINTER_INITIALIZER_POSTFIX = "_initNativeFunctionAddresses"; + private static final String CACHED_EXTS_VAR_NAME = "supported_extensions"; + private static final String PROFILE_MASK_VAR_NAME = "profileMask"; + private static final String EXTENSION_PREFIX = "GL_"; + private static final String CORE_PREFIX = "Open"; public static void generateClassPrologue(PrintWriter writer, boolean context_specific, boolean generate_error_checks) { writer.println("public class " + Utils.CONTEXT_CAPS_CLASS_NAME + " {"); writer.println("\tstatic final boolean DEBUG = " + Boolean.toString(generate_error_checks) + ";"); writer.println("\tfinal StateTracker tracker = new StateTracker();"); - writer.println("\tfinal IntBuffer scratch_int_buffer = BufferUtils.createIntBuffer(16);"); writer.println(); if ( !context_specific ) { writer.println("\tprivate static boolean " + STUBS_LOADED_NAME + " = false;"); @@ -109,6 +108,12 @@ writer.print("\t\t\t&& " + CACHED_EXTS_VAR_NAME + ".contains(\""); writer.print(translateFieldName(super_interface.getDeclaration().getSimpleName()) + "\")"); } + Alias alias_annotation = d.getAnnotation(Alias.class); + if ( alias_annotation != null ) { + writer.println(); + writer.print("\t\t\t|| " + CACHED_EXTS_VAR_NAME + ".contains(\""); + writer.print(translateFieldName(alias_annotation.value()) + "\")"); + } writer.println(";"); } @@ -165,10 +170,19 @@ public static void generateInitStubs(PrintWriter writer, InterfaceDeclaration d, boolean context_specific) { if ( d.getMethods().size() > 0 ) { if ( context_specific ) { + final Alias alias_annotation = d.getAnnotation(Alias.class); + if ( d.getAnnotation(ForceInit.class) != null ) writer.println("\t\t" + CACHED_EXTS_VAR_NAME + ".add(\"" + translateFieldName(d.getSimpleName()) + "\");"); - writer.print("\t\tif (" + CACHED_EXTS_VAR_NAME + ".contains(\""); + writer.print("\t\tif ("); + if ( alias_annotation != null ) + writer.print("("); + writer.print(CACHED_EXTS_VAR_NAME + ".contains(\""); writer.print(translateFieldName(d.getSimpleName()) + "\")"); + if ( alias_annotation != null ) { + writer.print(" || " + CACHED_EXTS_VAR_NAME + ".contains(\""); + writer.print(translateFieldName(alias_annotation.value()) + "\"))"); + } writer.print(" && !" + getAddressesInitializerName(d.getSimpleName()) + "("); if ( d.getAnnotation(DeprecatedGL.class) != null ) writer.print("forwardCompatible"); @@ -177,10 +191,16 @@ writer.print(","); writer.print("supported_extensions"); } - writer.println("))"); - //writer.print("\t\t\t" + CACHED_EXTS_VAR_NAME + ".remove(\""); + if ( alias_annotation != null ) { + writer.println(")) {"); + writer.print("\t\t\tremove(" + CACHED_EXTS_VAR_NAME + ", \""); + writer.println(translateFieldName(alias_annotation.value()) + "\");"); + } else + writer.println("))"); writer.print("\t\t\tremove(" + CACHED_EXTS_VAR_NAME + ", \""); writer.println(translateFieldName(d.getSimpleName()) + "\");"); + if ( alias_annotation != null ) + writer.println("\t\t}"); } else { writer.print("\t\tGLContext." + Utils.STUB_INITIALIZER_NAME + "(" + Utils.getSimpleClassName(d)); writer.println(".class, " + CACHED_EXTS_VAR_NAME + ", \"" + translateFieldName(d.getSimpleName()) + "\");"); @@ -210,6 +230,9 @@ writer.print(","); writer.print("Set supported_extensions"); } + + Alias alias_annotation = d.getAnnotation(Alias.class); + boolean aliased = alias_annotation != null && alias_annotation.postfix().length() > 0; writer.println(") {"); writer.println("\t\treturn "); @@ -267,9 +290,12 @@ writer.print(", "); } writer.print("}, "); + } else if ( aliased ) { + writer.print("GLContext.getFunctionAddress(new String[] {\"" + method.getSimpleName() + "\",\"" + method.getSimpleName() + alias_annotation.postfix() + "\"})) != 0"); } else writer.print("GLContext.getFunctionAddress("); - writer.print("\"" + method.getSimpleName() + "\")) != 0"); + if ( !aliased ) + writer.print("\"" + method.getSimpleName() + "\")) != 0"); if ( deprecated || dependent != null ) writer.print(')'); if ( optional ) diff --git a/src/java/org/lwjgl/util/generator/FieldsGenerator.java b/src/java/org/lwjgl/util/generator/FieldsGenerator.java index 689390b..a8a6d4b 100644 --- a/src/java/org/lwjgl/util/generator/FieldsGenerator.java +++ b/src/java/org/lwjgl/util/generator/FieldsGenerator.java @@ -32,47 +32,90 @@ package org.lwjgl.util.generator; -import com.sun.mirror.declaration.*; -import com.sun.mirror.type.*; +import java.io.PrintWriter; +import java.util.Collection; -import java.io.*; -import java.util.*; +import com.sun.mirror.declaration.FieldDeclaration; +import com.sun.mirror.declaration.Modifier; +import com.sun.mirror.type.PrimitiveType; +import com.sun.mirror.type.TypeMirror; public class FieldsGenerator { + private static void validateField(FieldDeclaration field) { + // Check if field is "public static final" Collection modifiers = field.getModifiers(); - if (modifiers.size() != 3 || !modifiers.contains(Modifier.PUBLIC) || !modifiers.contains(Modifier.STATIC) || - !modifiers.contains(Modifier.FINAL)) + if ( modifiers.size() != 3 + || !modifiers.contains(Modifier.PUBLIC) + || !modifiers.contains(Modifier.STATIC) + || !modifiers.contains(Modifier.FINAL) ) { throw new RuntimeException("Field " + field.getSimpleName() + " is not declared public static final"); + } + + // Check suported types (int, long, float, String) TypeMirror field_type = field.getType(); - if (!(field_type instanceof PrimitiveType)) - throw new RuntimeException("Field " + field.getSimpleName() + " is not a primitive type"); - PrimitiveType field_type_prim = (PrimitiveType)field_type; - if (field_type_prim.getKind() != PrimitiveType.Kind.INT && field_type_prim.getKind() != PrimitiveType.Kind.LONG) - throw new RuntimeException("Field " + field.getSimpleName() + " is not of type 'int' or 'long'"); + if ( field_type instanceof PrimitiveType ) { + PrimitiveType field_type_prim = (PrimitiveType)field_type; + PrimitiveType.Kind field_kind = field_type_prim.getKind(); + if ( field_kind != PrimitiveType.Kind.INT + && field_kind != PrimitiveType.Kind.LONG + && field_kind != PrimitiveType.Kind.FLOAT ) { + throw new RuntimeException("Field " + field.getSimpleName() + " is not of type 'int', 'long' or 'float'"); + } + } else if ( "java.lang.String".equals(field_type.toString()) ) { + } else { + throw new RuntimeException("Field " + field.getSimpleName() + " is not a primitive type or String"); + } + Object field_value = field.getConstantValue(); - if (field_value == null) + if ( field_value == null ) { throw new RuntimeException("Field " + field.getSimpleName() + " has no initial value"); + } } - private static void generateField(PrintWriter writer, FieldDeclaration field) { + private static void generateField(PrintWriter writer, FieldDeclaration field, FieldDeclaration prev_field) { validateField(field); Object value = field.getConstantValue(); String field_value_string; - if ( value.getClass().equals(Integer.class) ) - field_value_string = Integer.toHexString((Integer)field.getConstantValue()); - else - field_value_string = Long.toHexString((Long)field.getConstantValue()) + 'l'; + Class field_value_class = value.getClass(); + if ( field_value_class.equals(Integer.class) ) { + field_value_string = "0x" + Integer.toHexString((Integer)field.getConstantValue()).toUpperCase(); + } else if ( field_value_class.equals(Long.class) ) { + field_value_string = "0x" + Long.toHexString((Long)field.getConstantValue()).toUpperCase() + 'L'; + } else if ( field_value_class.equals(Float.class) ) { + field_value_string = field.getConstantValue() + "f"; + } else if ( field_value_class.equals(String.class) ) { + field_value_string = "\"" + field.getConstantValue() + "\""; + } else { + throw new RuntimeException("Field is of unexpected type. This means there is a bug in validateField()."); + } - Utils.printDocComment(writer, field); + boolean hadDoc = prev_field != null && prev_field.getDocComment() != null; + boolean hasDoc = field.getDocComment() != null; + boolean newBatch = prev_field == null || !prev_field.getType().equals(field.getType()) || (!hadDoc && field.getDocComment() != null) || (hadDoc && hasDoc && !prev_field.getDocComment().equals(field.getDocComment())); + // Print field declaration - writer.println("\tpublic static final " + field.getType().toString() + " " + field.getSimpleName() + " = 0x" + field_value_string + ";"); + if ( newBatch ) { + if ( prev_field != null ) + writer.println(";\n"); + + Utils.printDocComment(writer, field); + writer.print("\tpublic static final " + field.getType().toString() + " " + field.getSimpleName() + " = " + field_value_string); + } else + writer.print(",\n\t\t" + field.getSimpleName() + " = " + field_value_string); } public static void generateFields(PrintWriter writer, Collection fields) { - for (FieldDeclaration field : fields) - generateField(writer, field); + if ( 0 < fields.size() ) { + writer.println(); + FieldDeclaration prev_field = null; + for ( FieldDeclaration field : fields ) { + generateField(writer, field, prev_field); + prev_field = field; + } + writer.println(";"); + } } } diff --git a/src/java/org/lwjgl/util/generator/GLpointer.java b/src/java/org/lwjgl/util/generator/GLpointer.java index d11370e..a961fdf 100644 --- a/src/java/org/lwjgl/util/generator/GLpointer.java +++ b/src/java/org/lwjgl/util/generator/GLpointer.java @@ -40,4 +40,5 @@ @Target({ElementType.PARAMETER, ElementType.METHOD}) public @interface GLpointer { String value(); // The native pointer type. + boolean canBeNull() default false; // Whether the pointer may be null. }diff --git a/src/java/org/lwjgl/util/generator/GeneratorVisitor.java b/src/java/org/lwjgl/util/generator/GeneratorVisitor.java index f9f171f..6cdd397 100644 --- a/src/java/org/lwjgl/util/generator/GeneratorVisitor.java +++ b/src/java/org/lwjgl/util/generator/GeneratorVisitor.java @@ -50,8 +50,8 @@ * Generator visitor for the generator tool * * @author elias_naur - * @version $Revision: 3299 $ - * $Id: GeneratorVisitor.java 3299 2010-03-31 15:46:16Z spasi $ + * @version $Revision: 3355 $ + * $Id: GeneratorVisitor.java 3355 2010-05-27 22:56:29Z spasi $ */ public class GeneratorVisitor extends SimpleDeclarationVisitor { private final AnnotationProcessorEnvironment env; @@ -180,10 +180,7 @@ java_writer.println(); java_writer.println("package " + d.getPackage().getQualifiedName() + ";"); java_writer.println(); - java_writer.println("import org.lwjgl.LWJGLException;"); - java_writer.println("import org.lwjgl.BufferChecks;"); - // DISABLED: indirect buffer support - //java_writer.println("import org.lwjgl.NondirectBufferWrapper;"); + java_writer.println("import org.lwjgl.*;"); java_writer.println("import java.nio.*;"); java_writer.println(); Utils.printDocComment(java_writer, d); @@ -204,12 +201,12 @@ java_writer.println(); if (is_final) { // Write private constructor to avoid instantiation - java_writer.println("\tprivate " + Utils.getSimpleClassName(d) + "() {"); - java_writer.println("\t}"); + java_writer.println("\tprivate " + Utils.getSimpleClassName(d) + "() {}"); + } + if (d.getMethods().size() > 0 && !context_specific) { java_writer.println(); - } - if (d.getMethods().size() > 0 && !context_specific) java_writer.println("\tstatic native void " + Utils.STUB_INITIALIZER_NAME + "() throws LWJGLException;"); + } JavaMethodsGenerator.generateMethodsJava(env, type_map, java_writer, d, generate_error_checks, context_specific); java_writer.println("}"); java_writer.close(); diff --git a/src/java/org/lwjgl/util/generator/JavaMethodsGenerator.java b/src/java/org/lwjgl/util/generator/JavaMethodsGenerator.java index cabbd90..7897978 100644 --- a/src/java/org/lwjgl/util/generator/JavaMethodsGenerator.java +++ b/src/java/org/lwjgl/util/generator/JavaMethodsGenerator.java @@ -37,8 +37,8 @@ * This class generates the methods in the generated java source files. * * @author elias_naur - * @version $Revision: 3293 $ - * $Id: JavaMethodsGenerator.java 3293 2010-03-23 12:43:44Z spasi $ + * @version $Revision: 3355 $ + * $Id: JavaMethodsGenerator.java 3355 2010-05-27 22:56:29Z spasi $ */ import com.sun.mirror.apt.*; @@ -261,9 +261,12 @@ // DISABLED: indirect buffer support //printNondirectParameterCopies(writer, method, mode); if (has_result) { - if ( method.getAnnotation(GLreturn.class) == null ) - writer.println("\t\treturn " + Utils.RESULT_VAR_NAME + ";"); - else + if ( method.getAnnotation(GLreturn.class) == null ) { + if ( ByteBuffer.class.equals(Utils.getJavaType(result_type)) ) + writer.println("\t\treturn " + Utils.RESULT_VAR_NAME + ".order(ByteOrder.nativeOrder());"); // safeNewBuffer returns a direct ByteBuffer with BIG_ENDIAN order. + else + writer.println("\t\treturn " + Utils.RESULT_VAR_NAME + ";"); + } else Utils.printGLReturnPost(writer, method, method.getAnnotation(GLreturn.class)); } writer.println("\t}"); @@ -384,7 +387,10 @@ String auto_parameter_name = auto_type_annotation.value(); ParameterDeclaration auto_target_param = Utils.findParameter(method, auto_parameter_name); TypeInfo auto_target_type_info = typeinfos_instance.get(auto_target_param); - writer.print("(" + auto_parameter_name + ".remaining()"); + if ( auto_type_annotation.canBeNull() ) + writer.print("((" + auto_parameter_name + " == null ? 0 : " + auto_parameter_name + ".remaining())"); + else + writer.print("(" + auto_parameter_name + ".remaining()"); // Shift the remaining if the target parameter is multityped and there's no AutoType to track type boolean shift_remaining = !hasAnyParameterAutoTypeAnnotation(method, auto_target_param) && Utils.isParameterMultiTyped(auto_target_param); if (shift_remaining) { @@ -443,8 +449,13 @@ writer.print(offset == null ? "0" : offset); } else writer.print("0"); - } else if ( param.getAnnotation(GLpointer.class) != null ) { - writer.print(".getPointer()"); + } else { + GLpointer pointer_annotation = param.getAnnotation(GLpointer.class); + if ( pointer_annotation != null ) { + if ( pointer_annotation.canBeNull() ) + writer.print(" == null ? 0 : " + param.getSimpleName()); + writer.print(".getPointer()"); + } } } } @@ -490,7 +501,7 @@ cachedReference != null && (mode != Mode.BUFFEROBJECT || param.getAnnotation(BufferObject.class) == null) && param.getAnnotation(Result.class) == null) { - writer.print("\t\t" + Utils.CHECKS_CLASS_NAME + ".getReferences(caps)."); + writer.print("\t\tif ( LWJGLUtil.CHECKS ) " + Utils.CHECKS_CLASS_NAME + ".getReferences(caps)."); if(cachedReference.name().length() > 0) { writer.print(cachedReference.name()); } else { diff --git a/src/java/org/lwjgl/util/generator/Utils.java b/src/java/org/lwjgl/util/generator/Utils.java index 3d6aad8..dd2e2fa 100644 --- a/src/java/org/lwjgl/util/generator/Utils.java +++ b/src/java/org/lwjgl/util/generator/Utils.java @@ -36,8 +36,8 @@ * Various utility methods to the generator. * * @author elias_naur - * @version $Revision: 3299 $ - * $Id: Utils.java 3299 2010-03-31 15:46:16Z spasi $ + * @version $Revision: 3339 $ + * $Id: Utils.java 3339 2010-05-07 17:03:36Z spasi $ */ import java.io.PrintWriter; @@ -166,7 +166,9 @@ return null; } + // DISABLED: We always generate indirect methods. (affects OpenAL only at the time of this change) public static boolean isMethodIndirect(boolean generate_error_checks, boolean context_specific, MethodDeclaration method) { + /* for (ParameterDeclaration param : method.getParameters()) { if (isAddressableType(param.getType()) || getParameterAutoAnnotation(param) != null || param.getAnnotation(Constant.class) != null) @@ -176,6 +178,8 @@ method.getAnnotation(CachedResult.class) != null || (generate_error_checks && method.getAnnotation(NoErrorCheck.class) == null) || context_specific; + */ + return true; } public static String getNativeQualifiedName(String qualified_name) { diff --git a/src/native/common/extgl.h b/src/native/common/extgl.h index b26b92b..4bec56a 100644 --- a/src/native/common/extgl.h +++ b/src/native/common/extgl.h @@ -133,6 +133,9 @@ typedef uint64_t GLuint64; typedef struct __GLsync *GLsync; +/* AMD_debug_output callback function pointer. */ +typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam); + /* helper stuff */ /* initializes everything, call this right after the rc is created. the function returns true if successful */ diff --git a/src/native/common/org_lwjgl_openal_ALC10.c b/src/native/common/org_lwjgl_openal_ALC10.c index 33b9b81..be1b871 100644 --- a/src/native/common/org_lwjgl_openal_ALC10.c +++ b/src/native/common/org_lwjgl_openal_ALC10.c @@ -86,7 +86,7 @@ int length; int i=1; - if(alcString == NULL) { + if (alcString == NULL) { return NULL; } @@ -94,14 +94,21 @@ // These are encoded using \0 between elements and a finishing \0\0 switch(token) { case 0x1005: // ALC_DEVICE_SPECIFIER - case 0x310: // ALC_CAPTURE_DEVICE_SPECIFIER + case 0x310: // ALC_CAPTURE_DEVICE_SPECIFIER + // If deviceaddress is not 0, OpenAL returns a single device terminated by a + // single \0 character, if token is ALC_DEVICE_SPECIFIER or + // ALC_CAPTURE_DEVICE_SPECIFIER. + if (deviceaddress != 0) { + length = strlen(alcString); + break; + } case 0x1013: // ALC_ALL_DEVICES_SPECIFIER while (alcString[i - 1] != '\0' || alcString[i] != '\0') { i++; } length = i + 1; break; - default: + default: // e.g. ALC_DEFAULT_ALL_DEVICES_SPECIFIER length = strlen(alcString); } return NewStringNativeWithLength(env, alcString, length); diff --git a/src/native/common/org_lwjgl_opengl_AMDDebugOutputCallback.c b/src/native/common/org_lwjgl_opengl_AMDDebugOutputCallback.c new file mode 100644 index 0000000..231b4bd --- /dev/null +++ b/src/native/common/org_lwjgl_opengl_AMDDebugOutputCallback.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * JNI implementation of the AMD_debug_output function callback. + * + * @author Spasi + */ + +#include +#include "common_tools.h" +#include "extgl.h" +#include "org_lwjgl_opengl_AMDDebugOutputCallback.h" + +static void APIENTRY debugOutputCallback(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam) { + jclass callback_class; + jmethodID callback_method; + JNIEnv *env = getThreadEnv(); + if (env != NULL && !(*env)->ExceptionOccurred(env)) { + callback_class = (*env)->FindClass(env, "org/lwjgl/opengl/AMDDebugOutputUtil"); + if ( callback_class != NULL ) { + callback_method = (*env)->GetStaticMethodID(env, callback_class, "messageCallback", "(IIILjava/lang/String;Ljava/nio/ByteBuffer;)V"); + if ( callback_method != NULL ) { + (*env)->CallStaticVoidMethod(env, callback_class, callback_method, + (jint)id, + (jint)category, + (jint)severity, + NewStringNativeWithLength(env, message, length), + NULL + ); + } + } + } +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_AMDDebugOutputCallback_getFunctionPointer(JNIEnv *env, jclass clazz) { + return (jlong)(intptr_t)&debugOutputCallback; +} diff --git a/src/native/linux/context.c b/src/native/linux/context.c index 32af315..c4a7388 100644 --- a/src/native/linux/context.c +++ b/src/native/linux/context.c @@ -31,12 +31,12 @@ */ /** - * $Id: context.c 3116 2008-08-19 16:46:03Z spasi $ + * $Id: context.c 3357 2010-06-02 23:35:38Z spasi $ * * Include file to access public window features * * @author elias_naur - * @version $Revision: 3116 $ + * @version $Revision: 3357 $ */ #include @@ -119,6 +119,7 @@ int depth = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "depth", "I")); int stencil = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stencil", "I")); int samples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "samples", "I")); + int colorSamples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "colorSamples", "I")); int num_aux_buffers = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "num_aux_buffers", "I")); int accum_bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_bpp", "I")); int accum_alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_alpha", "I")); @@ -161,7 +162,10 @@ // Assume the caller has checked support for multisample if (samples > 0) { putAttrib(&attrib_list, GLX_SAMPLE_BUFFERS_ARB); putAttrib(&attrib_list, 1); - putAttrib(&attrib_list, GLX_SAMPLES_ARB); putAttrib(&attrib_list, samples); + putAttrib(&attrib_list, GLX_SAMPLES_ARB); putAttrib(&attrib_list, samples); // GLX_COVERAGE_SAMPLES_NV if colorSamples > 0 + if ( colorSamples > 0 ) { + putAttrib(&attrib_list, GLX_COLOR_SAMPLES_NV); putAttrib(&attrib_list, colorSamples); + } } if (sRGB) { putAttrib(&attrib_list, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB); putAttrib(&attrib_list, True); @@ -199,6 +203,7 @@ int depth = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "depth", "I")); int stencil = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stencil", "I")); int samples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "samples", "I")); + int colorSamples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "colorSamples", "I")); int num_aux_buffers = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "num_aux_buffers", "I")); int accum_bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_bpp", "I")); int accum_alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_alpha", "I")); @@ -228,7 +233,9 @@ // Assume the caller has checked support for multisample if (samples > 0) { putAttrib(&attrib_list, GLX_SAMPLE_BUFFERS_ARB); putAttrib(&attrib_list, 1); - putAttrib(&attrib_list, GLX_SAMPLES_ARB); putAttrib(&attrib_list, samples); + putAttrib(&attrib_list, GLX_SAMPLES_ARB); putAttrib(&attrib_list, samples); // GLX_COVERAGE_SAMPLES_NV if colorSamples > 0 + if ( colorSamples > 0 ) + putAttrib(&attrib_list, GLX_COLOR_SAMPLES_NV); putAttrib(&attrib_list, colorSamples); } if (sRGB) putAttrib(&attrib_list, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB); @@ -289,6 +296,11 @@ throwException(env, "Samples > 0 specified but there's no support for GLX_ARB_multisample"); return false; } + int colorSamples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "colorSamples", "I")); + if (colorSamples > 0 && !extension_flags.GLX_NV_multisample_coverage) { + throwException(env, "Color samples > 0 specified but there's no support for GLX_NV_multisample_coverage"); + return false; + } bool floating_point = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "floating_point", "Z")); if (floating_point && !(extension_flags.GLX13 && extension_flags.GLX_ARB_fbconfig_float)) { // We need GLX13 to support floating point throwException(env, "Floating point specified but there's no support for GLX_ARB_fbconfig_float"); diff --git a/src/native/linux/extgl_glx.c b/src/native/linux/extgl_glx.c index 1d8fc6c..7e07d48 100644 --- a/src/native/linux/extgl_glx.c +++ b/src/native/linux/extgl_glx.c @@ -160,6 +160,7 @@ extension_flags->GLX_EXT_fbconfig_packed_float = GLXQueryExtension(disp, screen, "GLX_EXT_fbconfig_packed_float"); extension_flags->GLX_ARB_framebuffer_sRGB = GLXQueryExtension(disp, screen, "GLX_ARB_framebuffer_sRGB") || GLXQueryExtension(disp, screen, "GLX_EXT_framebuffer_sRGB"); extension_flags->GLX_ARB_create_context = GLXQueryExtension(disp, screen, "GLX_ARB_create_context"); + extension_flags->GLX_NV_multisample_coverage = GLXQueryExtension(disp, screen, "GLX_NV_multisample_coverage"); } bool extgl_Open(JNIEnv *env) { diff --git a/src/native/linux/extgl_glx.h b/src/native/linux/extgl_glx.h index 56b9860..0ee85d8 100644 --- a/src/native/linux/extgl_glx.h +++ b/src/native/linux/extgl_glx.h @@ -271,6 +271,11 @@ #define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +/* GLX_NV_multisample_coverage */ +#define GLX_COVERAGE_SAMPLES_NV 100001 +#define GLX_COLOR_SAMPLES_NV 0x20B3 + + typedef XID GLXContextID; typedef XID GLXPixmap; typedef XID GLXDrawable; @@ -346,6 +351,7 @@ bool GLX_EXT_fbconfig_packed_float; bool GLX_ARB_framebuffer_sRGB; bool GLX_ARB_create_context; + bool GLX_NV_multisample_coverage; } GLXExtensions; /* Add _ to global symbols to avoid symbol clash with the OpenGL library */ diff --git a/src/native/linux/org_lwjgl_opengl_LinuxPeerInfo.c b/src/native/linux/org_lwjgl_opengl_LinuxPeerInfo.c index 0e9636f..08db112 100644 --- a/src/native/linux/org_lwjgl_opengl_LinuxPeerInfo.c +++ b/src/native/linux/org_lwjgl_opengl_LinuxPeerInfo.c @@ -1,40 +1,40 @@ -/* +/* * Copyright (c) 2002-2008 LWJGL Project * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are + * modification, are permitted provided that the following conditions are * met: - * - * * Redistributions of source code must retain the above copyright + * + * * Redistributions of source code must retain the above copyright * 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. * - * * Neither the name of 'LWJGL' nor the names of - * its contributors may be used to endorse or promote products derived + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * 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 - * 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 + * 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 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** - * $Id: org_lwjgl_opengl_LinuxPeerInfo.c 2985 2008-04-07 18:42:36Z matzon $ + * $Id: org_lwjgl_opengl_LinuxPeerInfo.c 3358 2010-06-03 15:49:26Z spasi $ * * @author elias_naur - * @version $Revision: 2985 $ + * @version $Revision: 3358 $ */ #include diff --git a/src/native/linux/org_lwjgl_opengl_Pbuffer.c b/src/native/linux/org_lwjgl_opengl_Pbuffer.c index 63a4f61..dfcc964 100644 --- a/src/native/linux/org_lwjgl_opengl_Pbuffer.c +++ b/src/native/linux/org_lwjgl_opengl_Pbuffer.c @@ -1,42 +1,42 @@ -/* +/* * Copyright (c) 2002-2008 LWJGL Project * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are + * modification, are permitted provided that the following conditions are * met: - * - * * Redistributions of source code must retain the above copyright + * + * * Redistributions of source code must retain the above copyright * 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. * - * * Neither the name of 'LWJGL' nor the names of - * its contributors may be used to endorse or promote products derived + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * 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 - * 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 + * 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 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** - * $Id: org_lwjgl_opengl_Pbuffer.c 2985 2008-04-07 18:42:36Z matzon $ + * $Id: org_lwjgl_opengl_Pbuffer.c 3358 2010-06-03 15:49:26Z spasi $ * * Linux Pbuffer. * * @author elias_naur - * @version $Revision: 2985 $ + * @version $Revision: 3358 $ */ #include diff --git a/src/native/windows/context.c b/src/native/windows/context.c index e658f91..0342081 100644 --- a/src/native/windows/context.c +++ b/src/native/windows/context.c @@ -31,10 +31,10 @@ */ /** - * $Id: context.c 3139 2008-10-28 09:53:16Z elias_naur $ + * $Id: context.c 3377 2010-07-12 12:04:56Z matzon $ * * @author elias_naue - * @version $Revision: 3139 $ + * @version $Revision: 3377 $ */ #include @@ -187,6 +187,7 @@ int depth = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "depth", "I")); int stencil = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stencil", "I")); int samples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "samples", "I")); + int colorSamples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "colorSamples", "I")); int num_aux_buffers = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "num_aux_buffers", "I")); int accum_bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_bpp", "I")); int accum_alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_alpha", "I")); @@ -220,8 +221,9 @@ if (pbuffer) { putAttrib(&attrib_list, WGL_DRAW_TO_PBUFFER_ARB); putAttrib(&attrib_list, TRUE); } - if (!getBooleanProperty(env, "org.lwjgl.opengl.Display.allowSoftwareOpenGL")) + if (!getBooleanProperty(env, "org.lwjgl.opengl.Display.allowSoftwareOpenGL")) { putAttrib(&attrib_list, WGL_ACCELERATION_ARB); putAttrib(&attrib_list, WGL_FULL_ACCELERATION_ARB); + } putAttrib(&attrib_list, WGL_PIXEL_TYPE_ARB); putAttrib(&attrib_list, pixel_type); putAttrib(&attrib_list, WGL_DOUBLE_BUFFER_ARB); putAttrib(&attrib_list, double_buffer ? TRUE : FALSE); putAttrib(&attrib_list, WGL_SUPPORT_OPENGL_ARB); putAttrib(&attrib_list, TRUE); @@ -234,7 +236,10 @@ // Assume caller checked extension availability if (samples > 0) { putAttrib(&attrib_list, WGL_SAMPLE_BUFFERS_ARB); putAttrib(&attrib_list, 1); - putAttrib(&attrib_list, WGL_SAMPLES_ARB); putAttrib(&attrib_list, samples); + putAttrib(&attrib_list, WGL_SAMPLES_ARB); putAttrib(&attrib_list, samples); // WGL_COVERAGE_SAMPLES_NV if colorSamples > 0 + if ( colorSamples > 0 ) { + putAttrib(&attrib_list, WGL_COLOR_SAMPLES_NV); putAttrib(&attrib_list, colorSamples); + } } putAttrib(&attrib_list, WGL_ACCUM_BITS_ARB); putAttrib(&attrib_list, accum_bpp); putAttrib(&attrib_list, WGL_ACCUM_ALPHA_BITS_ARB); putAttrib(&attrib_list, accum_alpha); @@ -385,7 +390,7 @@ return findPixelFormatFromBPP(env, hdc, pixel_format, bpp, double_buffer); } -static bool validateAndGetExtensions(JNIEnv *env, WGLExtensions *extensions, HDC dummy_hdc, HGLRC dummy_hglrc, int samples, bool floating_point, bool floating_point_packed, bool sRGB, jobject pixelFormatCaps) { +static bool validateAndGetExtensions(JNIEnv *env, WGLExtensions *extensions, HDC dummy_hdc, HGLRC dummy_hglrc, int samples, int colorSamples, bool floating_point, bool floating_point_packed, bool sRGB, jobject pixelFormatCaps) { if (!wglMakeCurrent(dummy_hdc, dummy_hglrc)) { throwException(env, "Could not bind context to dummy window"); return false; @@ -398,6 +403,10 @@ } if (samples > 0 && !extensions->WGL_ARB_multisample) { throwException(env, "No support for WGL_ARB_multisample"); + return false; + } + if (colorSamples > 0 && !extensions->WGL_NV_multisample_coverage) { + throwException(env, "No support for WGL_NV_multisample_coverage"); return false; } /* @@ -435,6 +444,7 @@ jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); int samples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "samples", "I")); + int colorSamples = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "colorSamples", "I")); bool floating_point = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "floating_point", "Z")); bool floating_point_packed = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "floating_point_packed", "Z")); bool sRGB = (bool)(*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "sRGB", "Z")); @@ -461,7 +471,7 @@ // Save the current HDC and HGLRC to avoid disruption saved_current_hdc = wglGetCurrentDC(); saved_current_hglrc = wglGetCurrentContext(); - if (validateAndGetExtensions(env, &extensions, dummy_hdc, dummy_hglrc, samples, floating_point, floating_point_packed, sRGB, pixelFormatCaps)) { + if (validateAndGetExtensions(env, &extensions, dummy_hdc, dummy_hglrc, samples, colorSamples, floating_point, floating_point_packed, sRGB, pixelFormatCaps)) { pixel_format_id = findPixelFormatARB(env, hdc, &extensions, pixel_format, pixelFormatCaps, use_hdc_bpp, window, pbuffer, double_buffer); } wglMakeCurrent(saved_current_hdc, saved_current_hglrc); diff --git a/src/native/windows/extgl_wgl.c b/src/native/windows/extgl_wgl.c index 75d8c6a..b8432b4 100644 --- a/src/native/windows/extgl_wgl.c +++ b/src/native/windows/extgl_wgl.c @@ -152,6 +152,7 @@ extensions->WGL_ARB_framebuffer_sRGB = WGLQueryExtension(extensions, "WGL_ARB_framebuffer_sRGB") || WGLQueryExtension(extensions, "WGL_EXT_framebuffer_sRGB"); extensions->WGL_EXT_pixel_format_packed_float = WGLQueryExtension(extensions, "WGL_EXT_pixel_format_packed_float"); extensions->WGL_ARB_create_context = WGLQueryExtension(extensions, "WGL_ARB_create_context"); + extensions->WGL_NV_multisample_coverage = WGLQueryExtension(extensions, "WGL_NV_multisample_coverage"); } static void extgl_InitWGLEXTExtensionsString(WGLExtensions *extensions) { diff --git a/src/native/windows/extgl_wgl.h b/src/native/windows/extgl_wgl.h index 43c06b4..e0ca55b 100644 --- a/src/native/windows/extgl_wgl.h +++ b/src/native/windows/extgl_wgl.h @@ -200,6 +200,15 @@ typedef HGLRC (APIENTRY * wglCreateContextAttribsARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); +/*---------------------------------------------------------------------*/ +/*------------ WGL_NV_multisample_coverage ----------------------------*/ +/*---------------------------------------------------------------------*/ + +#define WGL_COVERAGE_SAMPLES_NV 0x2042 +#define WGL_COLOR_SAMPLES_NV 0x20B9 + +/*---------------------------------------------------------------------*/ + typedef struct { bool WGL_ARB_buffer_region; bool WGL_ARB_extensions_string; @@ -217,6 +226,7 @@ bool WGL_ARB_framebuffer_sRGB; bool WGL_EXT_pixel_format_packed_float; bool WGL_ARB_create_context; + bool WGL_NV_multisample_coverage; wglGetExtensionsStringEXTPROC wglGetExtensionsStringEXT; diff --git a/src/native/windows/org_lwjgl_opengl_Pbuffer.c b/src/native/windows/org_lwjgl_opengl_Pbuffer.c index 9090f2f..92b3545 100644 --- a/src/native/windows/org_lwjgl_opengl_Pbuffer.c +++ b/src/native/windows/org_lwjgl_opengl_Pbuffer.c @@ -1,42 +1,42 @@ -/* +/* * Copyright (c) 2002-2008 LWJGL Project * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are + * modification, are permitted provided that the following conditions are * met: - * - * * Redistributions of source code must retain the above copyright + * + * * Redistributions of source code must retain the above copyright * 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. * - * * Neither the name of 'LWJGL' nor the names of - * its contributors may be used to endorse or promote products derived + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. - * + * * 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 - * 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 + * 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 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** - * $Id: org_lwjgl_opengl_Pbuffer.c 3149 2008-11-22 14:54:15Z elias_naur $ + * $Id: org_lwjgl_opengl_Pbuffer.c 3358 2010-06-03 15:49:26Z spasi $ * * Windows Pbuffer. * * @author elias_naur - * @version $Revision: 3149 $ + * @version $Revision: 3358 $ */ #include @@ -61,7 +61,7 @@ HDC saved_hdc; HGLRC saved_context; int pixel_format_id; - + dummy_hwnd = createDummyWindow(origin_x, origin_y); if (dummy_hwnd == NULL) { throwException(env, "Could not create dummy window"); @@ -136,7 +136,7 @@ const int *pBufferAttribs_ptr; WindowsPeerInfo *peer_info = (WindowsPeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); int pixel_format_id; - + if ( pBufferAttribs != NULL ) { pBufferAttribs_ptr = (const int *)(*env)->GetDirectBufferAddress(env, pBufferAttribs); } else { diff --git a/src/native/windows/org_lwjgl_opengl_WindowsPeerInfo.c b/src/native/windows/org_lwjgl_opengl_WindowsPeerInfo.c index 6508932..d0d9d12 100644 --- a/src/native/windows/org_lwjgl_opengl_WindowsPeerInfo.c +++ b/src/native/windows/org_lwjgl_opengl_WindowsPeerInfo.c @@ -31,10 +31,10 @@ */ /** - * $Id: org_lwjgl_opengl_WindowsPeerInfo.c 3148 2008-11-22 14:51:36Z elias_naur $ + * $Id: org_lwjgl_opengl_WindowsPeerInfo.c 3358 2010-06-03 15:49:26Z spasi $ * * @author elias_naur - * @version $Revision: 3148 $ + * @version $Revision: 3358 $ */ #include @@ -42,8 +42,7 @@ #include "context.h" #include "common_tools.h" -JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_WindowsPeerInfo_createHandle - (JNIEnv *env, jclass clazz) { +JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_WindowsPeerInfo_createHandle(JNIEnv *env, jclass clazz) { return newJavaManagedByteBuffer(env, sizeof(WindowsPeerInfo)); } diff --git a/src/templates/org/lwjgl/openal/AL10.java b/src/templates/org/lwjgl/openal/AL10.java index 26cc390..6a221a2 100644 --- a/src/templates/org/lwjgl/openal/AL10.java +++ b/src/templates/org/lwjgl/openal/AL10.java @@ -44,8 +44,8 @@ * AL.h version 1.0 * * @author Brian Matzon - * @version $Revision: 3288 $ - * $Id: AL10.java 3288 2010-03-16 17:58:48Z spasi $ + * @version $Revision: 3380 $ + * $Id: AL10.java 3380 2010-07-14 13:12:24Z matzon $ */ public interface AL10 { /** Bad value */ @@ -250,35 +250,28 @@ int AL_FREQUENCY = 0x2001; /** - * Sound buffers: frequency, in units of Hertz [Hz]. - * This is the number of samples per second. Half of the - * sample frequency marks the maximum significant - * frequency component. + * Sound buffers: The number of bits per sample for the + * data contained in the buffer. */ int AL_BITS = 0x2002; /** - * Sound buffers: frequency, in units of Hertz [Hz]. - * This is the number of samples per second. Half of the - * sample frequency marks the maximum significant - * frequency component. + * Sound buffers: The number of channels for the data + * contained in the buffer. */ int AL_CHANNELS = 0x2003; /** - * Sound buffers: frequency, in units of Hertz [Hz]. - * This is the number of samples per second. Half of the - * sample frequency marks the maximum significant - * frequency component. + * Sound buffers: Size in bytes of the buffer data. */ int AL_SIZE = 0x2004; /** - * Sound buffers: frequency, in units of Hertz [Hz]. - * This is the number of samples per second. Half of the - * sample frequency marks the maximum significant - * frequency component. - */ + * @deprecated This token is a relict of the early OpenAL days and is + * no longer supported. Neither the OpenAL spec nor OpenAL Soft define + * it. + */ + @Deprecated int AL_DATA = 0x2005; /** diff --git a/src/templates/org/lwjgl/openal/EFX10.java b/src/templates/org/lwjgl/openal/EFX10.java new file mode 100644 index 0000000..700edf3 --- /dev/null +++ b/src/templates/org/lwjgl/openal/EFX10.java @@ -0,0 +1,738 @@ +/* + * Copyright (c) 2002-2010 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.openal; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.util.generator.ALenum; +import org.lwjgl.util.generator.ALsizei; +import org.lwjgl.util.generator.ALuint; +import org.lwjgl.util.generator.ALvoid; +import org.lwjgl.util.generator.Alternate; +import org.lwjgl.util.generator.AutoSize; +import org.lwjgl.util.generator.Check; +import org.lwjgl.util.generator.Const; +import org.lwjgl.util.generator.Constant; +import org.lwjgl.util.generator.Indirect; +import org.lwjgl.util.generator.OutParameter; +import org.lwjgl.util.generator.Result; +import org.lwjgl.util.generator.StripPostfix; + +/** + * Implementation of the OpenAL extension ALC_EXT_EFX (version 1.0). Contains necessary fields, + * methods and a range of supplementary fields containing minimum, maximum and default values of + * the former fields. + *

      + * On top of regular functions defined in the ALC_EXT_EFX, there are also several convenience + * functions. Namely alGen... and alDelete... which do not take a Java buffer parameter and + * automatically create or delete a single object, without the overhead of using a buffer. + *

      + * For comments and specification of functions and fields, refer to the "Effects Extension Guide" + * which is part of the OpenAL SDK and can be downloaded from: + * http://connect.creativelabs.com/openal/Downloads/Forms/AllItems.aspx + * + * @author Ciardhubh + * @version $Revision$ + * $Id$ + */ +public interface EFX10 { + + // ALC properties + String ALC_EXT_EFX_NAME = "ALC_EXT_EFX"; + int ALC_EFX_MAJOR_VERSION = 0x20001; + int ALC_EFX_MINOR_VERSION = 0x20002; + int ALC_MAX_AUXILIARY_SENDS = 0x20003; + + // Listener properties + int AL_METERS_PER_UNIT = 0x20004; + + // Source properties + int AL_DIRECT_FILTER = 0x20005; + int AL_AUXILIARY_SEND_FILTER = 0x20006; + int AL_AIR_ABSORPTION_FACTOR = 0x20007; + int AL_ROOM_ROLLOFF_FACTOR = 0x20008; + int AL_CONE_OUTER_GAINHF = 0x20009; + int AL_DIRECT_FILTER_GAINHF_AUTO = 0x2000A; + int AL_AUXILIARY_SEND_FILTER_GAIN_AUTO = 0x2000B; + int AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO = 0x2000C; + + // Auxiliary effect slot properties + int AL_EFFECTSLOT_EFFECT = 0x0001; + int AL_EFFECTSLOT_GAIN = 0x0002; + int AL_EFFECTSLOT_AUXILIARY_SEND_AUTO = 0x0003; + // NULL auxiliary slot ID to disable a source send + int AL_EFFECTSLOT_NULL = 0x0000; + + // Effect parameters + // Reverb + int AL_REVERB_DENSITY = 0x0001; + int AL_REVERB_DIFFUSION = 0x0002; + int AL_REVERB_GAIN = 0x0003; + int AL_REVERB_GAINHF = 0x0004; + int AL_REVERB_DECAY_TIME = 0x0005; + int AL_REVERB_DECAY_HFRATIO = 0x0006; + int AL_REVERB_REFLECTIONS_GAIN = 0x0007; + int AL_REVERB_REFLECTIONS_DELAY = 0x0008; + int AL_REVERB_LATE_REVERB_GAIN = 0x0009; + int AL_REVERB_LATE_REVERB_DELAY = 0x000A; + int AL_REVERB_AIR_ABSORPTION_GAINHF = 0x000B; + int AL_REVERB_ROOM_ROLLOFF_FACTOR = 0x000C; + int AL_REVERB_DECAY_HFLIMIT = 0x000D; + // EAX Reverb + int AL_EAXREVERB_DENSITY = 0x0001; + int AL_EAXREVERB_DIFFUSION = 0x0002; + int AL_EAXREVERB_GAIN = 0x0003; + int AL_EAXREVERB_GAINHF = 0x0004; + int AL_EAXREVERB_GAINLF = 0x0005; + int AL_EAXREVERB_DECAY_TIME = 0x0006; + int AL_EAXREVERB_DECAY_HFRATIO = 0x0007; + int AL_EAXREVERB_DECAY_LFRATIO = 0x0008; + int AL_EAXREVERB_REFLECTIONS_GAIN = 0x0009; + int AL_EAXREVERB_REFLECTIONS_DELAY = 0x000A; + int AL_EAXREVERB_REFLECTIONS_PAN = 0x000B; + int AL_EAXREVERB_LATE_REVERB_GAIN = 0x000C; + int AL_EAXREVERB_LATE_REVERB_DELAY = 0x000D; + int AL_EAXREVERB_LATE_REVERB_PAN = 0x000E; + int AL_EAXREVERB_ECHO_TIME = 0x000F; + int AL_EAXREVERB_ECHO_DEPTH = 0x0010; + int AL_EAXREVERB_MODULATION_TIME = 0x0011; + int AL_EAXREVERB_MODULATION_DEPTH = 0x0012; + int AL_EAXREVERB_AIR_ABSORPTION_GAINHF = 0x0013; + int AL_EAXREVERB_HFREFERENCE = 0x0014; + int AL_EAXREVERB_LFREFERENCE = 0x0015; + int AL_EAXREVERB_ROOM_ROLLOFF_FACTOR = 0x0016; + int AL_EAXREVERB_DECAY_HFLIMIT = 0x0017; + // Chorus + int AL_CHORUS_WAVEFORM = 0x0001; + int AL_CHORUS_PHASE = 0x0002; + int AL_CHORUS_RATE = 0x0003; + int AL_CHORUS_DEPTH = 0x0004; + int AL_CHORUS_FEEDBACK = 0x0005; + int AL_CHORUS_DELAY = 0x0006; + // Distortion + int AL_DISTORTION_EDGE = 0x0001; + int AL_DISTORTION_GAIN = 0x0002; + int AL_DISTORTION_LOWPASS_CUTOFF = 0x0003; + int AL_DISTORTION_EQCENTER = 0x0004; + int AL_DISTORTION_EQBANDWIDTH = 0x0005; + // Echo + int AL_ECHO_DELAY = 0x0001; + int AL_ECHO_LRDELAY = 0x0002; + int AL_ECHO_DAMPING = 0x0003; + int AL_ECHO_FEEDBACK = 0x0004; + int AL_ECHO_SPREAD = 0x0005; + // Flanger + int AL_FLANGER_WAVEFORM = 0x0001; + int AL_FLANGER_PHASE = 0x0002; + int AL_FLANGER_RATE = 0x0003; + int AL_FLANGER_DEPTH = 0x0004; + int AL_FLANGER_FEEDBACK = 0x0005; + int AL_FLANGER_DELAY = 0x0006; + // Frequency shifter + int AL_FREQUENCY_SHIFTER_FREQUENCY = 0x0001; + int AL_FREQUENCY_SHIFTER_LEFT_DIRECTION = 0x0002; + int AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION = 0x0003; + // Vocal morpher + int AL_VOCAL_MORPHER_PHONEMEA = 0x0001; + int AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING = 0x0002; + int AL_VOCAL_MORPHER_PHONEMEB = 0x0003; + int AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING = 0x0004; + int AL_VOCAL_MORPHER_WAVEFORM = 0x0005; + int AL_VOCAL_MORPHER_RATE = 0x0006; + // Pitch shifter + int AL_PITCH_SHIFTER_COARSE_TUNE = 0x0001; + int AL_PITCH_SHIFTER_FINE_TUNE = 0x0002; + // Ring modulator + int AL_RING_MODULATOR_FREQUENCY = 0x0001; + int AL_RING_MODULATOR_HIGHPASS_CUTOFF = 0x0002; + int AL_RING_MODULATOR_WAVEFORM = 0x0003; + // Autowah + int AL_AUTOWAH_ATTACK_TIME = 0x0001; + int AL_AUTOWAH_RELEASE_TIME = 0x0002; + int AL_AUTOWAH_RESONANCE = 0x0003; + int AL_AUTOWAH_PEAK_GAIN = 0x0004; + // Compressor + int AL_COMPRESSOR_ONOFF = 0x0001; + // Equalizer + int AL_EQUALIZER_LOW_GAIN = 0x0001; + int AL_EQUALIZER_LOW_CUTOFF = 0x0002; + int AL_EQUALIZER_MID1_GAIN = 0x0003; + int AL_EQUALIZER_MID1_CENTER = 0x0004; + int AL_EQUALIZER_MID1_WIDTH = 0x0005; + int AL_EQUALIZER_MID2_GAIN = 0x0006; + int AL_EQUALIZER_MID2_CENTER = 0x0007; + int AL_EQUALIZER_MID2_WIDTH = 0x0008; + int AL_EQUALIZER_HIGH_GAIN = 0x0009; + int AL_EQUALIZER_HIGH_CUTOFF = 0x000A; + // Effect type + int AL_EFFECT_FIRST_PARAMETER = 0x0000; + int AL_EFFECT_LAST_PARAMETER = 0x8000; + int AL_EFFECT_TYPE = 0x8001; + // Effect types, used with AL_EFFECT_TYPE + int AL_EFFECT_NULL = 0x0000; + int AL_EFFECT_REVERB = 0x0001; + int AL_EFFECT_CHORUS = 0x0002; + int AL_EFFECT_DISTORTION = 0x0003; + int AL_EFFECT_ECHO = 0x0004; + int AL_EFFECT_FLANGER = 0x0005; + int AL_EFFECT_FREQUENCY_SHIFTER = 0x0006; + int AL_EFFECT_VOCAL_MORPHER = 0x0007; + int AL_EFFECT_PITCH_SHIFTER = 0x0008; + int AL_EFFECT_RING_MODULATOR = 0x0009; + int AL_EFFECT_AUTOWAH = 0x000A; + int AL_EFFECT_COMPRESSOR = 0x000B; + int AL_EFFECT_EQUALIZER = 0x000C; + int AL_EFFECT_EAXREVERB = 0x8000; + + // Filter properties + // Lowpass + int AL_LOWPASS_GAIN = 0x0001; + int AL_LOWPASS_GAINHF = 0x0002; + // Highpass + int AL_HIGHPASS_GAIN = 0x0001; + int AL_HIGHPASS_GAINLF = 0x0002; + // Bandpass + int AL_BANDPASS_GAIN = 0x0001; + int AL_BANDPASS_GAINLF = 0x0002; + int AL_BANDPASS_GAINHF = 0x0003; + // Filter type + int AL_FILTER_FIRST_PARAMETER = 0x0000; + int AL_FILTER_LAST_PARAMETER = 0x8000; + int AL_FILTER_TYPE = 0x8001; + // Filter types, used with the AL_FILTER_TYPE property + int AL_FILTER_NULL = 0x0000; + int AL_FILTER_LOWPASS = 0x0001; + int AL_FILTER_HIGHPASS = 0x0002; + int AL_FILTER_BANDPASS = 0x0003; + + // Auxiliary effect slot object functions + @ALvoid + void alGenAuxiliaryEffectSlots(@AutoSize("auxiliaryeffectslots") @ALsizei int n, @OutParameter @ALuint IntBuffer auxiliaryeffectslots); + + @Alternate(value = "alGenAuxiliaryEffectSlots", nativeAlt = true) + @ALvoid + void alGenAuxiliaryEffectSlots2(@Constant("1") @ALsizei int n, @Result @ALuint int auxiliaryeffectslot); + + @ALvoid + void alDeleteAuxiliaryEffectSlots(@AutoSize("auxiliaryeffectslots") @ALsizei int n, @OutParameter @ALuint IntBuffer auxiliaryeffectslots); + + @Alternate(value = "alDeleteAuxiliaryEffectSlots", nativeAlt = true) + @ALvoid + void alDeleteAuxiliaryEffectSlots2(@Constant("1") @ALsizei int n, @Indirect @ALuint int auxiliaryeffectslot); + + boolean alIsAuxiliaryEffectSlot(@ALuint int auxiliaryeffectslot); + + @ALvoid + void alAuxiliaryEffectSloti(@ALuint int auxiliaryeffectslot, @ALenum int param, int value); + + @StripPostfix("values") + @ALvoid + void alAuxiliaryEffectSlotiv(@ALuint int auxiliaryeffectslot, @ALenum int param, @Check("1") @Const IntBuffer values); + + @ALvoid + void alAuxiliaryEffectSlotf(@ALuint int auxiliaryeffectslot, @ALenum int param, float value); + + @StripPostfix("values") + @ALvoid + void alAuxiliaryEffectSlotfv(@ALuint int auxiliaryeffectslot, @ALenum int param, @Check("1") @Const FloatBuffer values); + + @ALvoid + void alGetAuxiliaryEffectSloti(@ALuint int auxiliaryeffectslot, @ALenum int param, @Result int value); + + @StripPostfix("intdata") + @ALvoid + void alGetAuxiliaryEffectSlotiv(@ALuint int auxiliaryeffectslot, @ALenum int param, @OutParameter @Check("1") IntBuffer intdata); + + @ALvoid + void alGetAuxiliaryEffectSlotf(@ALuint int auxiliaryeffectslot, @ALenum int param, @Result float value); + + @StripPostfix("floatdata") + @ALvoid + void alGetAuxiliaryEffectSlotfv(@ALuint int auxiliaryeffectslot, @ALenum int param, @OutParameter @Check("1") FloatBuffer floatdata); + + // Effect object functions + @ALvoid + void alGenEffects(@AutoSize("effects") @ALsizei int n, @OutParameter @ALuint IntBuffer effects); + + @Alternate(value = "alGenEffects", nativeAlt = true) + @ALvoid + void alGenEffects2(@Constant("1") @ALsizei int n, @Result @ALuint int effect); + + @ALvoid + void alDeleteEffects(@AutoSize("effects") @ALsizei int n, @OutParameter @ALuint IntBuffer effects); + + @Alternate(value = "alDeleteEffects", nativeAlt = true) + @ALvoid + void alDeleteEffects2(@Constant("1") @ALsizei int n, @Indirect @ALuint int effect); + + boolean alIsEffect(@ALuint int effect); + + @ALvoid + void alEffecti(@ALuint int effect, @ALenum int param, int value); + + @StripPostfix("values") + @ALvoid + void alEffectiv(@ALuint int effect, @ALenum int param, @Check("1") @Const IntBuffer values); + + @ALvoid + void alEffectf(@ALuint int effect, @ALenum int param, float value); + + @StripPostfix("values") + @ALvoid + void alEffectfv(@ALuint int effect, @ALenum int param, @Check("1") @Const FloatBuffer values); + + @ALvoid + void alGetEffecti(@ALuint int effect, @ALenum int param, @Result int value); + + @StripPostfix("intdata") + @ALvoid + void alGetEffectiv(@ALuint int effect, @ALenum int param, @OutParameter @Check("1") IntBuffer intdata); + + @ALvoid + void alGetEffectf(@ALuint int effect, @ALenum int param, @Result float value); + + @StripPostfix("floatdata") + @ALvoid + void alGetEffectfv(@ALuint int effect, @ALenum int param, @OutParameter @Check("1") FloatBuffer floatdata); + + // Filter object functions + @ALvoid + void alGenFilters(@AutoSize("filters") @ALsizei int n, @OutParameter @ALuint IntBuffer filters); + + @Alternate(value = "alGenFilters", nativeAlt = true) + @ALvoid + void alGenFilters2(@Constant("1") @ALsizei int n, @Result @ALuint int filter); + + @ALvoid + void alDeleteFilters(@AutoSize("filters") @ALsizei int n, @OutParameter @ALuint IntBuffer filters); + + @Alternate(value = "alDeleteFilters", nativeAlt = true) + @ALvoid + void alDeleteFilters2(@Constant("1") @ALsizei int n, @Indirect @ALuint int filter); + + boolean alIsFilter(@ALuint int filter); + + @ALvoid + void alFilteri(@ALuint int filter, @ALenum int param, int value); + + @StripPostfix("values") + @ALvoid + void alFilteriv(@ALuint int filter, @ALenum int param, @Check("1") @Const IntBuffer values); + + @ALvoid + void alFilterf(@ALuint int filter, @ALenum int param, float value); + + @StripPostfix("values") + @ALvoid + void alFilterfv(@ALuint int filter, @ALenum int param, @Check("1") @Const FloatBuffer values); + + @ALvoid + void alGetFilteri(@ALuint int filter, @ALenum int param, @Result int value); + + @StripPostfix("intdata") + @ALvoid + void alGetFilteriv(@ALuint int filter, @ALenum int param, @OutParameter @Check("1") IntBuffer intdata); + + @ALvoid + void alGetFilterf(@ALuint int filter, @ALenum int param, @Result float value); + + @StripPostfix("floatdata") + @ALvoid + void alGetFilterfv(@ALuint int filter, @ALenum int param, @OutParameter @Check("1") FloatBuffer floatdata); + + // Source property value ranges and defaults + float AL_MIN_AIR_ABSORPTION_FACTOR = 0.0f; + float AL_MAX_AIR_ABSORPTION_FACTOR = 10.0f; + float AL_DEFAULT_AIR_ABSORPTION_FACTOR = 0.0f; + float AL_MIN_ROOM_ROLLOFF_FACTOR = 0.0f; + float AL_MAX_ROOM_ROLLOFF_FACTOR = 10.0f; + float AL_DEFAULT_ROOM_ROLLOFF_FACTOR = 0.0f; + float AL_MIN_CONE_OUTER_GAINHF = 0.0f; + float AL_MAX_CONE_OUTER_GAINHF = 1.0f; + float AL_DEFAULT_CONE_OUTER_GAINHF = 1.0f; + int AL_MIN_DIRECT_FILTER_GAINHF_AUTO = AL10.AL_FALSE; + int AL_MAX_DIRECT_FILTER_GAINHF_AUTO = AL10.AL_TRUE; + int AL_DEFAULT_DIRECT_FILTER_GAINHF_AUTO = AL10.AL_TRUE; + int AL_MIN_AUXILIARY_SEND_FILTER_GAIN_AUTO = AL10.AL_FALSE; + int AL_MAX_AUXILIARY_SEND_FILTER_GAIN_AUTO = AL10.AL_TRUE; + int AL_DEFAULT_AUXILIARY_SEND_FILTER_GAIN_AUTO = AL10.AL_TRUE; + int AL_MIN_AUXILIARY_SEND_FILTER_GAINHF_AUTO = AL10.AL_FALSE; + int AL_MAX_AUXILIARY_SEND_FILTER_GAINHF_AUTO = AL10.AL_TRUE; + int AL_DEFAULT_AUXILIARY_SEND_FILTER_GAINHF_AUTO = AL10.AL_TRUE; + + // Listener property value ranges and defaults + float AL_MIN_METERS_PER_UNIT = Float.MIN_VALUE; + float AL_MAX_METERS_PER_UNIT = Float.MAX_VALUE; + float AL_DEFAULT_METERS_PER_UNIT = 1.0f; + + // Effect parameter ranges and defaults + // Reverb + float AL_REVERB_MIN_DENSITY = 0.0f; + float AL_REVERB_MAX_DENSITY = 1.0f; + float AL_REVERB_DEFAULT_DENSITY = 1.0f; + float AL_REVERB_MIN_DIFFUSION = 0.0f; + float AL_REVERB_MAX_DIFFUSION = 1.0f; + float AL_REVERB_DEFAULT_DIFFUSION = 1.0f; + float AL_REVERB_MIN_GAIN = 0.0f; + float AL_REVERB_MAX_GAIN = 1.0f; + float AL_REVERB_DEFAULT_GAIN = 0.32f; + float AL_REVERB_MIN_GAINHF = 0.0f; + float AL_REVERB_MAX_GAINHF = 1.0f; + float AL_REVERB_DEFAULT_GAINHF = 0.89f; + float AL_REVERB_MIN_DECAY_TIME = 0.1f; + float AL_REVERB_MAX_DECAY_TIME = 20.0f; + float AL_REVERB_DEFAULT_DECAY_TIME = 1.49f; + float AL_REVERB_MIN_DECAY_HFRATIO = 0.1f; + float AL_REVERB_MAX_DECAY_HFRATIO = 2.0f; + float AL_REVERB_DEFAULT_DECAY_HFRATIO = 0.83f; + float AL_REVERB_MIN_REFLECTIONS_GAIN = 0.0f; + float AL_REVERB_MAX_REFLECTIONS_GAIN = 3.16f; + float AL_REVERB_DEFAULT_REFLECTIONS_GAIN = 0.05f; + float AL_REVERB_MIN_REFLECTIONS_DELAY = 0.0f; + float AL_REVERB_MAX_REFLECTIONS_DELAY = 0.3f; + float AL_REVERB_DEFAULT_REFLECTIONS_DELAY = 0.007f; + float AL_REVERB_MIN_LATE_REVERB_GAIN = 0.0f; + float AL_REVERB_MAX_LATE_REVERB_GAIN = 10.0f; + float AL_REVERB_DEFAULT_LATE_REVERB_GAIN = 1.26f; + float AL_REVERB_MIN_LATE_REVERB_DELAY = 0.0f; + float AL_REVERB_MAX_LATE_REVERB_DELAY = 0.1f; + float AL_REVERB_DEFAULT_LATE_REVERB_DELAY = 0.011f; + float AL_REVERB_MIN_AIR_ABSORPTION_GAINHF = 0.892f; + float AL_REVERB_MAX_AIR_ABSORPTION_GAINHF = 1.0f; + float AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF = 0.994f; + float AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR = 0.0f; + float AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR = 10.0f; + float AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR = 0.0f; + int AL_REVERB_MIN_DECAY_HFLIMIT = AL10.AL_FALSE; + int AL_REVERB_MAX_DECAY_HFLIMIT = AL10.AL_TRUE; + int AL_REVERB_DEFAULT_DECAY_HFLIMIT = AL10.AL_TRUE; + // EAX reverb + float AL_EAXREVERB_MIN_DENSITY = 0.0f; + float AL_EAXREVERB_MAX_DENSITY = 1.0f; + float AL_EAXREVERB_DEFAULT_DENSITY = 1.0f; + float AL_EAXREVERB_MIN_DIFFUSION = 0.0f; + float AL_EAXREVERB_MAX_DIFFUSION = 1.0f; + float AL_EAXREVERB_DEFAULT_DIFFUSION = 1.0f; + float AL_EAXREVERB_MIN_GAIN = 0.0f; + float AL_EAXREVERB_MAX_GAIN = 1.0f; + float AL_EAXREVERB_DEFAULT_GAIN = 0.32f; + float AL_EAXREVERB_MIN_GAINHF = 0.0f; + float AL_EAXREVERB_MAX_GAINHF = 1.0f; + float AL_EAXREVERB_DEFAULT_GAINHF = 0.89f; + float AL_EAXREVERB_MIN_GAINLF = 0.0f; + float AL_EAXREVERB_MAX_GAINLF = 1.0f; + float AL_EAXREVERB_DEFAULT_GAINLF = 1.0f; + float AL_EAXREVERB_MIN_DECAY_TIME = 0.1f; + float AL_EAXREVERB_MAX_DECAY_TIME = 20.0f; + float AL_EAXREVERB_DEFAULT_DECAY_TIME = 1.49f; + float AL_EAXREVERB_MIN_DECAY_HFRATIO = 0.1f; + float AL_EAXREVERB_MAX_DECAY_HFRATIO = 2.0f; + float AL_EAXREVERB_DEFAULT_DECAY_HFRATIO = 0.83f; + float AL_EAXREVERB_MIN_DECAY_LFRATIO = 0.1f; + float AL_EAXREVERB_MAX_DECAY_LFRATIO = 2.0f; + float AL_EAXREVERB_DEFAULT_DECAY_LFRATIO = 1.0f; + float AL_EAXREVERB_MIN_REFLECTIONS_GAIN = 0.0f; + float AL_EAXREVERB_MAX_REFLECTIONS_GAIN = 3.16f; + float AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN = 0.05f; + float AL_EAXREVERB_MIN_REFLECTIONS_DELAY = 0.0f; + float AL_EAXREVERB_MAX_REFLECTIONS_DELAY = 0.3f; + float AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY = 0.007f; + float AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ = 0.0f; + float AL_EAXREVERB_MIN_LATE_REVERB_GAIN = 0.0f; + float AL_EAXREVERB_MAX_LATE_REVERB_GAIN = 10.0f; + float AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN = 1.26f; + float AL_EAXREVERB_MIN_LATE_REVERB_DELAY = 0.0f; + float AL_EAXREVERB_MAX_LATE_REVERB_DELAY = 0.1f; + float AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY = 0.011f; + float AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ = 0.0f; + float AL_EAXREVERB_MIN_ECHO_TIME = 0.075f; + float AL_EAXREVERB_MAX_ECHO_TIME = 0.25f; + float AL_EAXREVERB_DEFAULT_ECHO_TIME = 0.25f; + float AL_EAXREVERB_MIN_ECHO_DEPTH = 0.0f; + float AL_EAXREVERB_MAX_ECHO_DEPTH = 1.0f; + float AL_EAXREVERB_DEFAULT_ECHO_DEPTH = 0.0f; + float AL_EAXREVERB_MIN_MODULATION_TIME = 0.04f; + float AL_EAXREVERB_MAX_MODULATION_TIME = 4.0f; + float AL_EAXREVERB_DEFAULT_MODULATION_TIME = 0.25f; + float AL_EAXREVERB_MIN_MODULATION_DEPTH = 0.0f; + float AL_EAXREVERB_MAX_MODULATION_DEPTH = 1.0f; + float AL_EAXREVERB_DEFAULT_MODULATION_DEPTH = 0.0f; + float AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF = 0.892f; + float AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF = 1.0f; + float AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF = 0.994f; + float AL_EAXREVERB_MIN_HFREFERENCE = 1000.0f; + float AL_EAXREVERB_MAX_HFREFERENCE = 20000.0f; + float AL_EAXREVERB_DEFAULT_HFREFERENCE = 5000.0f; + float AL_EAXREVERB_MIN_LFREFERENCE = 20.0f; + float AL_EAXREVERB_MAX_LFREFERENCE = 1000.0f; + float AL_EAXREVERB_DEFAULT_LFREFERENCE = 250.0f; + float AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR = 0.0f; + float AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR = 10.0f; + float AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR = 0.0f; + int AL_EAXREVERB_MIN_DECAY_HFLIMIT = AL10.AL_FALSE; + int AL_EAXREVERB_MAX_DECAY_HFLIMIT = AL10.AL_TRUE; + int AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT = AL10.AL_TRUE; + // Chorus + int AL_CHORUS_WAVEFORM_SINUSOID = 0; + int AL_CHORUS_WAVEFORM_TRIANGLE = 1; + int AL_CHORUS_MIN_WAVEFORM = 0; + int AL_CHORUS_MAX_WAVEFORM = 1; + int AL_CHORUS_DEFAULT_WAVEFORM = 1; + int AL_CHORUS_MIN_PHASE = -180; + int AL_CHORUS_MAX_PHASE = 180; + int AL_CHORUS_DEFAULT_PHASE = 90; + float AL_CHORUS_MIN_RATE = 0.0f; + float AL_CHORUS_MAX_RATE = 10.0f; + float AL_CHORUS_DEFAULT_RATE = 1.1f; + float AL_CHORUS_MIN_DEPTH = 0.0f; + float AL_CHORUS_MAX_DEPTH = 1.0f; + float AL_CHORUS_DEFAULT_DEPTH = 0.1f; + float AL_CHORUS_MIN_FEEDBACK = -1.0f; + float AL_CHORUS_MAX_FEEDBACK = 1.0f; + float AL_CHORUS_DEFAULT_FEEDBACK = 0.25f; + float AL_CHORUS_MIN_DELAY = 0.0f; + float AL_CHORUS_MAX_DELAY = 0.016f; + float AL_CHORUS_DEFAULT_DELAY = 0.016f; + // Distortion + float AL_DISTORTION_MIN_EDGE = 0.0f; + float AL_DISTORTION_MAX_EDGE = 1.0f; + float AL_DISTORTION_DEFAULT_EDGE = 0.2f; + float AL_DISTORTION_MIN_GAIN = 0.01f; + float AL_DISTORTION_MAX_GAIN = 1.0f; + float AL_DISTORTION_DEFAULT_GAIN = 0.05f; + float AL_DISTORTION_MIN_LOWPASS_CUTOFF = 80.0f; + float AL_DISTORTION_MAX_LOWPASS_CUTOFF = 24000.0f; + float AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF = 8000.0f; + float AL_DISTORTION_MIN_EQCENTER = 80.0f; + float AL_DISTORTION_MAX_EQCENTER = 24000.0f; + float AL_DISTORTION_DEFAULT_EQCENTER = 3600.0f; + float AL_DISTORTION_MIN_EQBANDWIDTH = 80.0f; + float AL_DISTORTION_MAX_EQBANDWIDTH = 24000.0f; + float AL_DISTORTION_DEFAULT_EQBANDWIDTH = 3600.0f; + // Echo + float AL_ECHO_MIN_DELAY = 0.0f; + float AL_ECHO_MAX_DELAY = 0.207f; + float AL_ECHO_DEFAULT_DELAY = 0.1f; + float AL_ECHO_MIN_LRDELAY = 0.0f; + float AL_ECHO_MAX_LRDELAY = 0.404f; + float AL_ECHO_DEFAULT_LRDELAY = 0.1f; + float AL_ECHO_MIN_DAMPING = 0.0f; + float AL_ECHO_MAX_DAMPING = 0.99f; + float AL_ECHO_DEFAULT_DAMPING = 0.5f; + float AL_ECHO_MIN_FEEDBACK = 0.0f; + float AL_ECHO_MAX_FEEDBACK = 1.0f; + float AL_ECHO_DEFAULT_FEEDBACK = 0.5f; + float AL_ECHO_MIN_SPREAD = -1.0f; + float AL_ECHO_MAX_SPREAD = 1.0f; + float AL_ECHO_DEFAULT_SPREAD = -1.0f; + // Flanger + int AL_FLANGER_WAVEFORM_SINUSOID = 0; + int AL_FLANGER_WAVEFORM_TRIANGLE = 1; + int AL_FLANGER_MIN_WAVEFORM = 0; + int AL_FLANGER_MAX_WAVEFORM = 1; + int AL_FLANGER_DEFAULT_WAVEFORM = 1; + int AL_FLANGER_MIN_PHASE = -180; + int AL_FLANGER_MAX_PHASE = 180; + int AL_FLANGER_DEFAULT_PHASE = 0; + float AL_FLANGER_MIN_RATE = 0.0f; + float AL_FLANGER_MAX_RATE = 10.0f; + float AL_FLANGER_DEFAULT_RATE = 0.27f; + float AL_FLANGER_MIN_DEPTH = 0.0f; + float AL_FLANGER_MAX_DEPTH = 1.0f; + float AL_FLANGER_DEFAULT_DEPTH = 1.0f; + float AL_FLANGER_MIN_FEEDBACK = -1.0f; + float AL_FLANGER_MAX_FEEDBACK = 1.0f; + float AL_FLANGER_DEFAULT_FEEDBACK = -0.5f; + float AL_FLANGER_MIN_DELAY = 0.0f; + float AL_FLANGER_MAX_DELAY = 0.004f; + float AL_FLANGER_DEFAULT_DELAY = 0.002f; + // Frequency shifter + float AL_FREQUENCY_SHIFTER_MIN_FREQUENCY = 0.0f; + float AL_FREQUENCY_SHIFTER_MAX_FREQUENCY = 24000.0f; + float AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY = 0.0f; + int AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION = 0; + int AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION = 2; + int AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION = 0; + int AL_FREQUENCY_SHIFTER_DIRECTION_DOWN = 0; + int AL_FREQUENCY_SHIFTER_DIRECTION_UP = 1; + int AL_FREQUENCY_SHIFTER_DIRECTION_OFF = 2; + int AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION = 0; + int AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION = 2; + int AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION = 0; + // Vocal morpher + int AL_VOCAL_MORPHER_MIN_PHONEMEA = 0; + int AL_VOCAL_MORPHER_MAX_PHONEMEA = 29; + int AL_VOCAL_MORPHER_DEFAULT_PHONEMEA = 0; + int AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING = -24; + int AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING = 24; + int AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING = 0; + int AL_VOCAL_MORPHER_MIN_PHONEMEB = 0; + int AL_VOCAL_MORPHER_MAX_PHONEMEB = 29; + int AL_VOCAL_MORPHER_DEFAULT_PHONEMEB = 10; + int AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING = -24; + int AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING = 24; + int AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING = 0; + int AL_VOCAL_MORPHER_PHONEME_A = 0; + int AL_VOCAL_MORPHER_PHONEME_E = 1; + int AL_VOCAL_MORPHER_PHONEME_I = 2; + int AL_VOCAL_MORPHER_PHONEME_O = 3; + int AL_VOCAL_MORPHER_PHONEME_U = 4; + int AL_VOCAL_MORPHER_PHONEME_AA = 5; + int AL_VOCAL_MORPHER_PHONEME_AE = 6; + int AL_VOCAL_MORPHER_PHONEME_AH = 7; + int AL_VOCAL_MORPHER_PHONEME_AO = 8; + int AL_VOCAL_MORPHER_PHONEME_EH = 9; + int AL_VOCAL_MORPHER_PHONEME_ER = 10; + int AL_VOCAL_MORPHER_PHONEME_IH = 11; + int AL_VOCAL_MORPHER_PHONEME_IY = 12; + int AL_VOCAL_MORPHER_PHONEME_UH = 13; + int AL_VOCAL_MORPHER_PHONEME_UW = 14; + int AL_VOCAL_MORPHER_PHONEME_B = 15; + int AL_VOCAL_MORPHER_PHONEME_D = 16; + int AL_VOCAL_MORPHER_PHONEME_F = 17; + int AL_VOCAL_MORPHER_PHONEME_G = 18; + int AL_VOCAL_MORPHER_PHONEME_J = 19; + int AL_VOCAL_MORPHER_PHONEME_K = 20; + int AL_VOCAL_MORPHER_PHONEME_L = 21; + int AL_VOCAL_MORPHER_PHONEME_M = 22; + int AL_VOCAL_MORPHER_PHONEME_N = 23; + int AL_VOCAL_MORPHER_PHONEME_P = 24; + int AL_VOCAL_MORPHER_PHONEME_R = 25; + int AL_VOCAL_MORPHER_PHONEME_S = 26; + int AL_VOCAL_MORPHER_PHONEME_T = 27; + int AL_VOCAL_MORPHER_PHONEME_V = 28; + int AL_VOCAL_MORPHER_PHONEME_Z = 29; + int AL_VOCAL_MORPHER_WAVEFORM_SINUSOID = 0; + int AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE = 1; + int AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH = 2; + int AL_VOCAL_MORPHER_MIN_WAVEFORM = 0; + int AL_VOCAL_MORPHER_MAX_WAVEFORM = 2; + int AL_VOCAL_MORPHER_DEFAULT_WAVEFORM = 0; + float AL_VOCAL_MORPHER_MIN_RATE = 0.0f; + float AL_VOCAL_MORPHER_MAX_RATE = 10.0f; + float AL_VOCAL_MORPHER_DEFAULT_RATE = 1.41f; + // Pitch shifter + int AL_PITCH_SHIFTER_MIN_COARSE_TUNE = -12; + int AL_PITCH_SHIFTER_MAX_COARSE_TUNE = 12; + int AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE = 12; + int AL_PITCH_SHIFTER_MIN_FINE_TUNE = -50; + int AL_PITCH_SHIFTER_MAX_FINE_TUNE = 50; + int AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE = 0; + // Ring modulator + float AL_RING_MODULATOR_MIN_FREQUENCY = 0.0f; + float AL_RING_MODULATOR_MAX_FREQUENCY = 8000.0f; + float AL_RING_MODULATOR_DEFAULT_FREQUENCY = 440.0f; + float AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF = 0.0f; + float AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF = 24000.0f; + float AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF = 800.0f; + int AL_RING_MODULATOR_SINUSOID = 0; + int AL_RING_MODULATOR_SAWTOOTH = 1; + int AL_RING_MODULATOR_SQUARE = 2; + int AL_RING_MODULATOR_MIN_WAVEFORM = 0; + int AL_RING_MODULATOR_MAX_WAVEFORM = 2; + int AL_RING_MODULATOR_DEFAULT_WAVEFORM = 0; + // Autowah + float AL_AUTOWAH_MIN_ATTACK_TIME = 0.0001f; + float AL_AUTOWAH_MAX_ATTACK_TIME = 1.0f; + float AL_AUTOWAH_DEFAULT_ATTACK_TIME = 0.06f; + float AL_AUTOWAH_MIN_RELEASE_TIME = 0.0001f; + float AL_AUTOWAH_MAX_RELEASE_TIME = 1.0f; + float AL_AUTOWAH_DEFAULT_RELEASE_TIME = 0.06f; + float AL_AUTOWAH_MIN_RESONANCE = 2.0f; + float AL_AUTOWAH_MAX_RESONANCE = 1000.0f; + float AL_AUTOWAH_DEFAULT_RESONANCE = 1000.0f; + float AL_AUTOWAH_MIN_PEAK_GAIN = 0.00003f; + float AL_AUTOWAH_MAX_PEAK_GAIN = 31621.0f; + float AL_AUTOWAH_DEFAULT_PEAK_GAIN = 11.22f; + // Compressor + int AL_COMPRESSOR_MIN_ONOFF = 0; + int AL_COMPRESSOR_MAX_ONOFF = 1; + int AL_COMPRESSOR_DEFAULT_ONOFF = 1; + // Equalizer + float AL_EQUALIZER_MIN_LOW_GAIN = 0.126f; + float AL_EQUALIZER_MAX_LOW_GAIN = 7.943f; + float AL_EQUALIZER_DEFAULT_LOW_GAIN = 1.0f; + float AL_EQUALIZER_MIN_LOW_CUTOFF = 50.0f; + float AL_EQUALIZER_MAX_LOW_CUTOFF = 800.0f; + float AL_EQUALIZER_DEFAULT_LOW_CUTOFF = 200.0f; + float AL_EQUALIZER_MIN_MID1_GAIN = 0.126f; + float AL_EQUALIZER_MAX_MID1_GAIN = 7.943f; + float AL_EQUALIZER_DEFAULT_MID1_GAIN = 1.0f; + float AL_EQUALIZER_MIN_MID1_CENTER = 200.0f; + float AL_EQUALIZER_MAX_MID1_CENTER = 3000.0f; + float AL_EQUALIZER_DEFAULT_MID1_CENTER = 500.0f; + float AL_EQUALIZER_MIN_MID1_WIDTH = 0.01f; + float AL_EQUALIZER_MAX_MID1_WIDTH = 1.0f; + float AL_EQUALIZER_DEFAULT_MID1_WIDTH = 1.0f; + float AL_EQUALIZER_MIN_MID2_GAIN = 0.126f; + float AL_EQUALIZER_MAX_MID2_GAIN = 7.943f; + float AL_EQUALIZER_DEFAULT_MID2_GAIN = 1.0f; + float AL_EQUALIZER_MIN_MID2_CENTER = 1000.0f; + float AL_EQUALIZER_MAX_MID2_CENTER = 8000.0f; + float AL_EQUALIZER_DEFAULT_MID2_CENTER = 3000.0f; + float AL_EQUALIZER_MIN_MID2_WIDTH = 0.01f; + float AL_EQUALIZER_MAX_MID2_WIDTH = 1.0f; + float AL_EQUALIZER_DEFAULT_MID2_WIDTH = 1.0f; + float AL_EQUALIZER_MIN_HIGH_GAIN = 0.126f; + float AL_EQUALIZER_MAX_HIGH_GAIN = 7.943f; + float AL_EQUALIZER_DEFAULT_HIGH_GAIN = 1.0f; + float AL_EQUALIZER_MIN_HIGH_CUTOFF = 4000.0f; + float AL_EQUALIZER_MAX_HIGH_CUTOFF = 16000.0f; + float AL_EQUALIZER_DEFAULT_HIGH_CUTOFF = 6000.0f; + + // Filter parameter ranges and defaults + // Lowpass + float LOWPASS_MIN_GAIN = 0.0f; + float LOWPASS_MAX_GAIN = 1.0f; + float LOWPASS_DEFAULT_GAIN = 1.0f; + float LOWPASS_MIN_GAINHF = 0.0f; + float LOWPASS_MAX_GAINHF = 1.0f; + float LOWPASS_DEFAULT_GAINHF = 1.0f; + // Highpass + float HIGHPASS_MIN_GAIN = 0.0f; + float HIGHPASS_MAX_GAIN = 1.0f; + float HIGHPASS_DEFAULT_GAIN = 1.0f; + float HIGHPASS_MIN_GAINLF = 0.0f; + float HIGHPASS_MAX_GAINLF = 1.0f; + float HIGHPASS_DEFAULT_GAINLF = 1.0f; + // Bandpass + float BANDPASS_MIN_GAIN = 0.0f; + float BANDPASS_MAX_GAIN = 1.0f; + float BANDPASS_DEFAULT_GAIN = 1.0f; + float BANDPASS_MIN_GAINHF = 0.0f; + float BANDPASS_MAX_GAINHF = 1.0f; + float BANDPASS_DEFAULT_GAINHF = 1.0f; + float BANDPASS_MIN_GAINLF = 0.0f; + float BANDPASS_MAX_GAINLF = 1.0f; + float BANDPASS_DEFAULT_GAINLF = 1.0f; +} diff --git a/src/templates/org/lwjgl/opengl/AMD_debug_output.java b/src/templates/org/lwjgl/opengl/AMD_debug_output.java new file mode 100644 index 0000000..662612b --- /dev/null +++ b/src/templates/org/lwjgl/opengl/AMD_debug_output.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.util.generator.*; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +@Alias(value = "AMDX_debug_output", postfix = "X") +public interface AMD_debug_output { + + /** Tokens accepted by GetIntegerv: */ + int GL_MAX_DEBUG_MESSAGE_LENGTH_AMD = 0x9143, + GL_MAX_DEBUG_LOGGED_MESSAGES_AMD = 0x9144, + GL_DEBUG_LOGGED_MESSAGES_AMD = 0x9145; + + /** + * Tokens accepted by DebugMessageEnableAMD, GetDebugMessageLogAMD, + * DebugMessageInsertAMD, and DEBUGPROCAMD callback function + * for <severity>: + */ + int GL_DEBUG_SEVERITY_HIGH_AMD = 0x9146, + GL_DEBUG_SEVERITY_MEDIUM_AMD = 0x9147, + GL_DEBUG_SEVERITY_LOW_AMD = 0x9148; + + /** + * Tokens accepted by DebugMessageEnableAMD, GetDebugMessageLogAMD, + * and DEBUGPROCAMD callback function for <category>: + */ + int GL_DEBUG_CATEGORY_API_ERROR_AMD = 0x9149, + GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD = 0x914A, + GL_DEBUG_CATEGORY_DEPRECATION_AMD = 0x914B, + GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD = 0x914C, + GL_DEBUG_CATEGORY_PERFORMANCE_AMD = 0x914D, + GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD = 0x914E, + GL_DEBUG_CATEGORY_APPLICATION_AMD = 0x914F, + GL_DEBUG_CATEGORY_OTHER_AMD = 0x9150; + + void glDebugMessageEnableAMD(@GLenum int category, @GLenum int severity, @AutoSize(value = "ids", canBeNull = true) @GLsizei int count, @Check(canBeNull = true) @Const @GLuint IntBuffer ids, boolean enabled); + + void glDebugMessageInsertAMD(@GLenum int category, @GLenum int severity, @GLuint int id, @AutoSize("buf") @GLsizei int length, @Const @GLchar ByteBuffer buf); + + @Alternate("glDebugMessageInsertAMD") + void glDebugMessageInsertAMD(@GLenum int category, @GLenum int severity, @GLuint int id, @Constant("buf.length()") @GLsizei int length, CharSequence buf); + + /** + * The {@code AMDDebugOutputCallback.Handler} implementation passed to this method will be used for + * AMD_debug_output messages. If callback is null, any previously registered handler for the current + * thread will be unregistered and stop receiving messages. + *

      + * The userParam buffer will be passed to the GL, but the current implementation will ignore it and + * never return it to the handler. Instead, users are encouraged to use a custom callback handler + * implentation to store context-specific data. + * + * @param callback the callback function to use + * @param userParam the user-specified data + */ + void glDebugMessageCallbackAMD(@GLpointer(value = "GLDEBUGPROCAMD", canBeNull = true) AMDDebugOutputCallback callback, @Check(canBeNull = true) @GLvoid ByteBuffer userParam); + + @GLuint + int glGetDebugMessageLogAMD(@GLuint int count, + @AutoSize(value = "messageLog", canBeNull = true) @GLsizei int logSize, + @Check(value = "count", canBeNull = true) @GLenum IntBuffer categories, + @Check(value = "count", canBeNull = true) @GLuint IntBuffer severities, + @Check(value = "count", canBeNull = true) @GLuint IntBuffer ids, + @Check(value = "count", canBeNull = true) @GLsizei IntBuffer lengths, + @Check(canBeNull = true) @OutParameter @GLchar ByteBuffer messageLog); + +} \ No newline at end of file diff --git a/src/templates/org/lwjgl/opengl/AMD_name_gen_delete.java b/src/templates/org/lwjgl/opengl/AMD_name_gen_delete.java new file mode 100644 index 0000000..89094ea --- /dev/null +++ b/src/templates/org/lwjgl/opengl/AMD_name_gen_delete.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.util.generator.*; + +import java.nio.IntBuffer; + +public interface AMD_name_gen_delete { + + /** Accepted as the <identifier> parameter of GenNamesAMD and DeleteNamesAMD: */ + int GL_DATA_BUFFER_AMD = 0x9151, + GL_PERFORMANCE_MONITOR_AMD = 0x9152, + GL_QUERY_OBJECT_AMD = 0x9153, + GL_VERTEX_ARRAY_OBJECT_AMD = 0x9154, + GL_SAMPLER_OBJECT_AMD = 0x9155; + + void glGenNamesAMD(@GLenum int identifier, @AutoSize("names") @GLuint int num, @OutParameter @GLuint IntBuffer names); + + @Alternate("glGenNamesAMD") + @GLreturn("names") + void glGenNamesAMD2(@GLenum int identifier, @Constant("1") @GLsizei int num, @OutParameter @GLuint IntBuffer names); + + void glDeleteNamesAMD(@GLenum int identifier, @AutoSize("names") @GLsizei int num, @Const @GLuint IntBuffer names); + + @Alternate("glDeleteNamesAMD") + void glDeleteNamesAMD(@GLenum int identifier, @Constant("1") @GLsizei int num, @Constant(value = "APIUtils.getBufferInt().put(0, name), 0", keepParam = true) int name); + + boolean glIsNameAMD(@GLenum int identifier, @GLuint int name); + +} \ No newline at end of file diff --git a/src/templates/org/lwjgl/opengl/AMD_transform_feedback3_lines_triangles.java b/src/templates/org/lwjgl/opengl/AMD_transform_feedback3_lines_triangles.java new file mode 100644 index 0000000..ef91a3b --- /dev/null +++ b/src/templates/org/lwjgl/opengl/AMD_transform_feedback3_lines_triangles.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +public interface AMD_transform_feedback3_lines_triangles { + +} \ No newline at end of file diff --git a/src/templates/org/lwjgl/opengl/ARB_texture_buffer_object_rgb32.java b/src/templates/org/lwjgl/opengl/ARB_texture_buffer_object_rgb32.java index 3a0a868..301ed5e 100644 --- a/src/templates/org/lwjgl/opengl/ARB_texture_buffer_object_rgb32.java +++ b/src/templates/org/lwjgl/opengl/ARB_texture_buffer_object_rgb32.java @@ -31,5 +31,8 @@ */ package org.lwjgl.opengl; +import org.lwjgl.util.generator.Alias; + +@Alias("EXT_texture_buffer_object_rgb32") public interface ARB_texture_buffer_object_rgb32 { }diff --git a/src/templates/org/lwjgl/opengl/ARB_texture_compression_bptc.java b/src/templates/org/lwjgl/opengl/ARB_texture_compression_bptc.java index 9ea5ab7..0687da1 100644 --- a/src/templates/org/lwjgl/opengl/ARB_texture_compression_bptc.java +++ b/src/templates/org/lwjgl/opengl/ARB_texture_compression_bptc.java @@ -31,9 +31,11 @@ */ package org.lwjgl.opengl; +import org.lwjgl.util.generator.Alias; import org.lwjgl.util.generator.Extension; @Extension(postfix = "ARB", className = "ARBTextureCompressionBPTC") +@Alias("EXT_texture_compression_bptc") public interface ARB_texture_compression_bptc { /** diff --git a/src/templates/org/lwjgl/opengl/ATI_vertex_array_object.java b/src/templates/org/lwjgl/opengl/ATI_vertex_array_object.java index 3b387cc..d351007 100644 --- a/src/templates/org/lwjgl/opengl/ATI_vertex_array_object.java +++ b/src/templates/org/lwjgl/opengl/ATI_vertex_array_object.java @@ -71,6 +71,11 @@ @StripPostfix("params") void glGetObjectBufferivATI(@GLuint int buffer, @GLenum int pname, @OutParameter @Check IntBuffer params); + @Alternate("glGetObjectBufferivATI") + @GLreturn("params") + @StripPostfix("params") + void glGetObjectBufferivATI2(@GLuint int buffer, @GLenum int pname, @OutParameter IntBuffer params); + void glFreeObjectBufferATI(@GLuint int buffer); void glArrayObjectATI(@GLenum int array, int size, @GLenum int type, @GLsizei int stride, @GLuint int buffer, @GLuint int offset); diff --git a/src/templates/org/lwjgl/opengl/EXT_direct_state_access.java b/src/templates/org/lwjgl/opengl/EXT_direct_state_access.java index baf8d98..7b9beb0 100644 --- a/src/templates/org/lwjgl/opengl/EXT_direct_state_access.java +++ b/src/templates/org/lwjgl/opengl/EXT_direct_state_access.java @@ -519,11 +519,11 @@ value parameters */ - @Optional(reason = "AMD does not expose this (last driver checked: 10.3)") + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") void glEnableClientStateiEXT(@GLenum int array, @GLuint int index); - @Optional(reason = "AMD does not expose this (last driver checked: 10.3)") + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") void glDisableClientStateiEXT(@GLenum int array, @GLuint int index); @@ -565,7 +565,7 @@ and before state value parameters */ - @Optional(reason = "AMD does not expose this (last driver checked: 10.3)") + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @StripPostfix("params") void glGetFloati_vEXT(@GLenum int pname, @GLuint int index, @OutParameter @Check("16") FloatBuffer params); @@ -576,7 +576,7 @@ @StripPostfix("params") void glGetFloati_vEXT2(@GLenum int pname, @GLuint int index, @OutParameter FloatBuffer params); - @Optional(reason = "AMD does not expose this (last driver checked: 10.3)") + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @StripPostfix("params") void glGetDoublei_vEXT(@GLenum int pname, @GLuint int index, @OutParameter @Check("16") DoubleBuffer params); @@ -587,7 +587,7 @@ @StripPostfix("params") void glGetDoublei_vEXT2(@GLenum int pname, @GLuint int index, @OutParameter DoubleBuffer params); - @Optional(reason = "AMD does not expose this (last driver checked: 10.3)") + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @StripPostfix(value = "params", hasPostfix = false) void glGetPointeri_vEXT(@GLenum int pname, @GLuint int index, @Result @GLvoid ByteBuffer params); @@ -1343,6 +1343,7 @@ OpenGL 3.1: New buffer data copy command */ + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL31,GL_ARB_copy_buffer") void glNamedCopyBufferSubDataEXT(@GLuint int readBuffer, @GLuint int writeBuffer, @GLintptr long readoffset, @GLintptr long writeoffset, @GLsizeiptr long size); @@ -1386,44 +1387,55 @@ and change the final parameter from "const void *" to "intptr offset" */ + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @DeprecatedGL void glVertexArrayVertexOffsetEXT(@GLuint int vaobj, @GLuint int buffer, int size, @GLenum int type, @GLsizei int stride, @GLintptr long offset); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @DeprecatedGL void glVertexArrayColorOffsetEXT(@GLuint int vaobj, @GLuint int buffer, int size, @GLenum int type, @GLsizei int stride, @GLintptr long offset); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @DeprecatedGL void glVertexArrayEdgeFlagOffsetEXT(@GLuint int vaobj, @GLuint int buffer, @GLsizei int stride, @GLintptr long offset); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") void glVertexArrayIndexOffsetEXT(@GLuint int vaobj, @GLuint int buffer, @GLenum int type, @GLsizei int stride, @GLintptr long offset); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @DeprecatedGL void glVertexArrayNormalOffsetEXT(@GLuint int vaobj, @GLuint int buffer, @GLenum int type, @GLsizei int stride, @GLintptr long offset); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @DeprecatedGL void glVertexArrayTexCoordOffsetEXT(@GLuint int vaobj, @GLuint int buffer, int size, @GLenum int type, @GLsizei int stride, @GLintptr long offset); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @DeprecatedGL void glVertexArrayMultiTexCoordOffsetEXT(@GLuint int vaobj, @GLuint int buffer, @GLenum int texunit, int size, @GLenum int type, @GLsizei int stride, @GLintptr long offset); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @DeprecatedGL void glVertexArrayFogCoordOffsetEXT(@GLuint int vaobj, @GLuint int buffer, @GLenum int type, @GLsizei int stride, @GLintptr long offset); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @DeprecatedGL void glVertexArraySecondaryColorOffsetEXT(@GLuint int vaobj, @GLuint int buffer, int size, @GLenum int type, @GLsizei int stride, @GLintptr long offset); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") void glVertexArrayVertexAttribOffsetEXT(@GLuint int vaobj, @GLuint int buffer, @GLuint int index, int size, @GLenum int type, boolean normalized, @GLsizei int stride, @GLintptr long offset); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") void glVertexArrayVertexAttribIOffsetEXT(@GLuint int vaobj, @GLuint int buffer, @GLuint int index, int size, @GLenum int type, @GLsizei int stride, @GLintptr long offset); @@ -1433,9 +1445,11 @@ "uint vaobj" parameter */ + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") void glEnableVertexArrayEXT(@GLuint int vaobj, @GLenum int array); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") void glDisableVertexArrayEXT(@GLuint int vaobj, @GLenum int array); @@ -1445,9 +1459,11 @@ and add an initial "uint vaobj" parameter */ + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") void glEnableVertexArrayAttribEXT(@GLuint int vaobj, @GLuint int index); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") void glDisableVertexArrayAttribEXT(@GLuint int vaobj, @GLuint int index); @@ -1455,6 +1471,7 @@ OpenGL 3.0: New queries for vertex array objects */ + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @StripPostfix("param") void glGetVertexArrayIntegervEXT(@GLuint int vaobj, @GLenum int pname, @OutParameter @Check("16") IntBuffer param); @@ -1465,10 +1482,12 @@ @StripPostfix("param") void glGetVertexArrayIntegervEXT2(@GLuint int vaobj, @GLenum int pname, @OutParameter IntBuffer param); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @StripPostfix("param") void glGetVertexArrayPointervEXT(@GLuint int vaobj, @GLenum int pname, @Result @GLvoid ByteBuffer param); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @StripPostfix(value = "param") void glGetVertexArrayIntegeri_vEXT(@GLuint int vaobj, @GLuint int index, @GLenum int pname, @OutParameter @Check("16") IntBuffer param); @@ -1479,6 +1498,7 @@ @StripPostfix(value = "param", postfix = "_v") void glGetVertexArrayIntegeri_vEXT2(@GLuint int vaobj, @GLuint int index, @GLenum int pname, @OutParameter IntBuffer param); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @StripPostfix(value = "param") void glGetVertexArrayPointeri_vEXT(@GLuint int vaobj, @GLuint int index, @GLenum int pname, @Result @GLvoid ByteBuffer param); @@ -1502,12 +1522,14 @@ * * @return A ByteBuffer representing the mapped buffer memory. */ + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") @CachedResult(isRange = true) @GLvoid @AutoResultSize("length") ByteBuffer glMapNamedBufferRangeEXT(@GLuint int buffer, @GLintptr long offset, @GLsizeiptr long length, @GLbitfield int access); + @Optional(reason = "AMD does not expose this (last driver checked: 10.5)") @Dependent("OpenGL30") void glFlushMappedNamedBufferRangeEXT(@GLuint int buffer, @GLintptr long offset, @GLsizeiptr long length); diff --git a/src/templates/org/lwjgl/opengl/GL11.java b/src/templates/org/lwjgl/opengl/GL11.java index 249dd78..f648caa 100644 --- a/src/templates/org/lwjgl/opengl/GL11.java +++ b/src/templates/org/lwjgl/opengl/GL11.java @@ -39,8 +39,8 @@ * The core OpenGL1.1 API. * * @author cix_foo - * @version $Revision: 3316 $ - * $Id: GL11.java 3316 2010-04-09 23:57:40Z spasi $ + * @version $Revision: 3338 $ + * $Id: GL11.java 3338 2010-05-01 09:19:00Z spasi $ */ @DeprecatedGL public interface GL11 { @@ -1147,7 +1147,7 @@ String glGetString(int name); @DeprecatedGL - void glGetPolygonStipple(@OutParameter @BufferObject(BufferKind.PackPBO) @Check("1024") @GLubyte ByteBuffer mask); + void glGetPolygonStipple(@OutParameter @BufferObject(BufferKind.PackPBO) @Check("128") @GLubyte ByteBuffer mask); @DeprecatedGL boolean glIsList(@GLuint int list); @@ -1252,7 +1252,7 @@ void glMatrixMode(@GLenum int mode); @DeprecatedGL - void glPolygonStipple(@BufferObject(BufferKind.UnpackPBO) @Check("1024") @Const @GLubyte ByteBuffer mask); + void glPolygonStipple(@BufferObject(BufferKind.UnpackPBO) @Check("128") @Const @GLubyte ByteBuffer mask); void glPolygonOffset(float factor, float units); diff --git a/src/templates/org/lwjgl/opengl/GL15.java b/src/templates/org/lwjgl/opengl/GL15.java index f88f7d3..bc9adf0 100644 --- a/src/templates/org/lwjgl/opengl/GL15.java +++ b/src/templates/org/lwjgl/opengl/GL15.java @@ -74,7 +74,7 @@ int GL_BUFFER_MAPPED = 0x88BC; int GL_BUFFER_MAP_POINTER = 0x88BD; - int FOG_COORD_SRC = GL14.GL_FOG_COORDINATE_SOURCE; + int GL_FOG_COORD_SRC = GL14.GL_FOG_COORDINATE_SOURCE; int GL_FOG_COORD = GL14.GL_FOG_COORDINATE; int GL_CURRENT_FOG_COORD = GL14.GL_CURRENT_FOG_COORDINATE; int GL_FOG_COORD_ARRAY_TYPE = GL14.GL_FOG_COORDINATE_ARRAY_TYPE; diff --git a/src/templates/org/lwjgl/opengl/NV_fence.java b/src/templates/org/lwjgl/opengl/NV_fence.java index 6822f70..a5a5e89 100644 --- a/src/templates/org/lwjgl/opengl/NV_fence.java +++ b/src/templates/org/lwjgl/opengl/NV_fence.java @@ -42,7 +42,14 @@ void glGenFencesNV(@AutoSize("piFences") @GLsizei int n, @OutParameter @GLuint IntBuffer piFences); + @Alternate("glGenFencesNV") + @GLreturn("piFences") + void glGenFencesNV2(@Constant("1") @GLsizei int n, @OutParameter @GLuint IntBuffer piFences); + void glDeleteFencesNV(@AutoSize("piFences") @GLsizei int n, @Const @GLuint IntBuffer piFences); + + @Alternate("glDeleteFencesNV") + void glDeleteFencesNV(@Constant("1") @GLsizei int n, @Const @GLuint @Constant(value = "APIUtils.getBufferInt().put(0, fence), 0", keepParam = true) int fence); void glSetFenceNV(@GLuint int fence, @GLenum int condition); diff --git a/src/templates/org/lwjgl/opengl/NV_multisample_coverage.java b/src/templates/org/lwjgl/opengl/NV_multisample_coverage.java new file mode 100644 index 0000000..fcdfbf0 --- /dev/null +++ b/src/templates/org/lwjgl/opengl/NV_multisample_coverage.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * 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. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +public interface NV_multisample_coverage { + + /** + * Accepted by the <pname> parameter of GetBooleanv, GetDoublev, + * GetIntegerv, and GetFloatv: + */ + int GL_COVERAGE_SAMPLES_NV = 0x80A9; + int GL_COLOR_SAMPLES_NV = 0x8E20; + +} \ No newline at end of file