From 21b3c3d8189715cf6a60ed51c4d186e8122bdecf Mon Sep 17 00:00:00 2001 From: Ioannis Tsakpinis Date: Thu, 27 May 2010 22:56:29 +0000 Subject: [PATCH] Added PixelFormat support for framebuffer CSAA (NV_multisample_coverage, WGL & GLX only). Added support for AMD_name_gen_delete and AMD_debug_output. The AMDDebugOutputCallback class enables query-less message handling. Added support for extension aliases. --- build.xml | 1 + platform_build/build-generator.xml | 2 + .../lwjgl/opengl/AMDDebugOutputCallback.java | 162 ++++++++++++++++++ .../org/lwjgl/opengl/AMDDebugOutputUtil.java | 59 +++++++ .../org/lwjgl/opengl/AbstractDrawable.java | 3 +- src/java/org/lwjgl/opengl/DrawableLWJGL.java | 3 +- src/java/org/lwjgl/opengl/GLContext.java | 16 ++ src/java/org/lwjgl/opengl/PixelFormat.java | 51 +++++- src/java/org/lwjgl/opengl/SharedDrawable.java | 3 +- .../org/lwjgl/test/opengl/VersionTest.java | 4 +- src/java/org/lwjgl/util/generator/Alias.java | 54 ++++++ .../org/lwjgl/util/generator/AutoSize.java | 1 + .../ContextCapabilitiesGenerator.java | 49 ++++-- .../lwjgl/util/generator/FieldsGenerator.java | 122 +++++++------ .../org/lwjgl/util/generator/GLpointer.java | 1 + .../util/generator/GeneratorVisitor.java | 8 +- .../util/generator/JavaMethodsGenerator.java | 14 +- src/native/common/extgl.h | 3 + .../org_lwjgl_opengl_AMDDebugOutputCallback.c | 67 ++++++++ src/native/linux/context.c | 15 +- src/native/linux/extgl_glx.c | 1 + src/native/linux/extgl_glx.h | 6 + src/native/windows/context.c | 14 +- src/native/windows/extgl_wgl.c | 1 + src/native/windows/extgl_wgl.h | 10 ++ .../org/lwjgl/opengl/AMD_debug_output.java | 87 ++++++++++ .../org/lwjgl/opengl/AMD_name_gen_delete.java | 60 +++++++ .../ARB_texture_buffer_object_rgb32.java | 3 + .../opengl/ARB_texture_compression_bptc.java | 2 + .../lwjgl/opengl/NV_multisample_coverage.java | 43 +++++ 30 files changed, 781 insertions(+), 84 deletions(-) create mode 100644 src/java/org/lwjgl/opengl/AMDDebugOutputCallback.java create mode 100644 src/java/org/lwjgl/opengl/AMDDebugOutputUtil.java create mode 100644 src/java/org/lwjgl/util/generator/Alias.java create mode 100644 src/native/common/org_lwjgl_opengl_AMDDebugOutputCallback.c create mode 100644 src/templates/org/lwjgl/opengl/AMD_debug_output.java create mode 100644 src/templates/org/lwjgl/opengl/AMD_name_gen_delete.java create mode 100644 src/templates/org/lwjgl/opengl/NV_multisample_coverage.java diff --git a/build.xml b/build.xml index d6257678..29bbca0e 100644 --- a/build.xml +++ b/build.xml @@ -253,6 +253,7 @@ + diff --git a/platform_build/build-generator.xml b/platform_build/build-generator.xml index cd58bb3e..4f56b3f6 100644 --- a/platform_build/build-generator.xml +++ b/platform_build/build-generator.xml @@ -13,8 +13,10 @@ + + diff --git a/src/java/org/lwjgl/opengl/AMDDebugOutputCallback.java b/src/java/org/lwjgl/opengl/AMDDebugOutputCallback.java new file mode 100644 index 00000000..00381613 --- /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 00000000..1227833e --- /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/AbstractDrawable.java b/src/java/org/lwjgl/opengl/AbstractDrawable.java index 8702c48c..18778a86 100644 --- a/src/java/org/lwjgl/opengl/AbstractDrawable.java +++ b/src/java/org/lwjgl/opengl/AbstractDrawable.java @@ -5,7 +5,6 @@ import org.lwjgl.LWJGLUtil; /** * @author Spasi - * @since 22 Απρ 2010 */ abstract class AbstractDrawable implements DrawableLWJGL { @@ -79,4 +78,4 @@ abstract class AbstractDrawable implements DrawableLWJGL { throw new IllegalStateException("The Drawable has no context available."); } -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/opengl/DrawableLWJGL.java b/src/java/org/lwjgl/opengl/DrawableLWJGL.java index ca677420..b79c806f 100644 --- a/src/java/org/lwjgl/opengl/DrawableLWJGL.java +++ b/src/java/org/lwjgl/opengl/DrawableLWJGL.java @@ -4,7 +4,6 @@ import org.lwjgl.LWJGLException; /** * @author Spasi - * @since 23 Απρ 2010 */ interface DrawableLWJGL extends Drawable { @@ -22,4 +21,4 @@ interface DrawableLWJGL extends Drawable { */ Context createSharedContext() throws LWJGLException; -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/opengl/GLContext.java b/src/java/org/lwjgl/opengl/GLContext.java index 2d98fee9..240c1e63 100644 --- a/src/java/org/lwjgl/opengl/GLContext.java +++ b/src/java/org/lwjgl/opengl/GLContext.java @@ -169,6 +169,22 @@ public final class GLContext { 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/PixelFormat.java b/src/java/org/lwjgl/opengl/PixelFormat.java index bb8d3faa..c3a8a91e 100644 --- a/src/java/org/lwjgl/opengl/PixelFormat.java +++ b/src/java/org/lwjgl/opengl/PixelFormat.java @@ -66,6 +66,14 @@ public final class PixelFormat { * 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 @@ public final class PixelFormat { 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 @@ public final class PixelFormat { this.stencil = pf.stencil; this.samples = pf.samples; + this.colorSamples = pf.colorSamples; this.num_aux_buffers = pf.num_aux_buffers; @@ -245,6 +260,38 @@ public final class PixelFormat { 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 index e2174143..f96d0f63 100644 --- a/src/java/org/lwjgl/opengl/SharedDrawable.java +++ b/src/java/org/lwjgl/opengl/SharedDrawable.java @@ -35,7 +35,6 @@ import org.lwjgl.LWJGLException; /** * @author Spasi - * @since 20 Απρ 2010 */ /** @@ -55,4 +54,4 @@ public final class SharedDrawable extends AbstractDrawable { throw new UnsupportedOperationException(); } -} \ No newline at end of file +} diff --git a/src/java/org/lwjgl/test/opengl/VersionTest.java b/src/java/org/lwjgl/test/opengl/VersionTest.java index bb2d8100..44d94437 100644 --- a/src/java/org/lwjgl/test/opengl/VersionTest.java +++ b/src/java/org/lwjgl/test/opengl/VersionTest.java @@ -148,7 +148,7 @@ public final class VersionTest { boolean success = false; boolean check; - if ( majorInput < 3 || minorInput == 0 ) { + 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:"); @@ -252,4 +252,4 @@ public final class VersionTest { System.exit(-1); } -} \ No newline at end of file +} 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 00000000..3983174d --- /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 5022514a..90318dcb 100644 --- a/src/java/org/lwjgl/util/generator/AutoSize.java +++ b/src/java/org/lwjgl/util/generator/AutoSize.java @@ -49,4 +49,5 @@ import java.lang.annotation.ElementType; 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 df302081..84146976 100644 --- a/src/java/org/lwjgl/util/generator/ContextCapabilitiesGenerator.java +++ b/src/java/org/lwjgl/util/generator/ContextCapabilitiesGenerator.java @@ -51,13 +51,13 @@ import com.sun.mirror.type.InterfaceType; */ 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 + " {"); @@ -108,6 +108,12 @@ public class ContextCapabilitiesGenerator { 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(";"); } @@ -164,10 +170,19 @@ public class ContextCapabilitiesGenerator { 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"); @@ -176,10 +191,16 @@ public class ContextCapabilitiesGenerator { 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 +231,9 @@ public class ContextCapabilitiesGenerator { 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 "); @@ -266,9 +290,12 @@ public class ContextCapabilitiesGenerator { 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 7ca5e8c9..a8a6d4b0 100644 --- a/src/java/org/lwjgl/util/generator/FieldsGenerator.java +++ b/src/java/org/lwjgl/util/generator/FieldsGenerator.java @@ -32,70 +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)) { - throw new RuntimeException("Field " + field.getSimpleName() + " is not declared public static final"); - } + // 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) ) { + 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) { - 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 (field_type.toString().equals("java.lang.String")) { - } else { - throw new RuntimeException("Field " + field.getSimpleName() + " is not a primitive type or String"); - } + // Check suported types (int, long, float, String) + TypeMirror field_type = field.getType(); + 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) { - throw new RuntimeException("Field " + field.getSimpleName() + " has no initial value"); - } + Object field_value = field.getConstantValue(); + if ( field_value == null ) { + throw new RuntimeException("Field " + field.getSimpleName() + " has no initial value"); + } } - private static void generateField(PrintWriter writer, FieldDeclaration field) { - validateField(field); + private static void generateField(PrintWriter writer, FieldDeclaration field, FieldDeclaration prev_field) { + validateField(field); - Object value = field.getConstantValue(); - String field_value_string; - Class field_value_class = value.getClass(); - if (field_value_class.equals(Integer.class)) { - field_value_string = "0x" + Integer.toHexString((Integer) field.getConstantValue()); - } else if (field_value_class.equals(Long.class)) { - field_value_string = "0x" + Long.toHexString((Long) field.getConstantValue()) + '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()."); - } + Object value = field.getConstantValue(); + String field_value_string; + 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); - // Print field declaration - writer.println("\tpublic static final " + field.getType().toString() + " " + field.getSimpleName() + " = " + field_value_string + ";"); + 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 + 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 d42f5901..ef77e874 100644 --- a/src/java/org/lwjgl/util/generator/GLpointer.java +++ b/src/java/org/lwjgl/util/generator/GLpointer.java @@ -40,4 +40,5 @@ import java.lang.annotation.ElementType; @Target({ElementType.PARAMETER, ElementType.METHOD}) public @interface GLpointer { String value(); // The native pointer type. + boolean canBeNull() default false; // Whether the pointer may be null. } \ No newline at end of file diff --git a/src/java/org/lwjgl/util/generator/GeneratorVisitor.java b/src/java/org/lwjgl/util/generator/GeneratorVisitor.java index caba2a7e..a3f74177 100644 --- a/src/java/org/lwjgl/util/generator/GeneratorVisitor.java +++ b/src/java/org/lwjgl/util/generator/GeneratorVisitor.java @@ -201,12 +201,12 @@ public class GeneratorVisitor extends SimpleDeclarationVisitor { 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(); + java_writer.println("\tprivate " + Utils.getSimpleClassName(d) + "() {}"); } - if (d.getMethods().size() > 0 && !context_specific) + if (d.getMethods().size() > 0 && !context_specific) { + java_writer.println(); 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 810afe1f..456770c8 100644 --- a/src/java/org/lwjgl/util/generator/JavaMethodsGenerator.java +++ b/src/java/org/lwjgl/util/generator/JavaMethodsGenerator.java @@ -387,7 +387,10 @@ public class JavaMethodsGenerator { 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) { @@ -446,8 +449,13 @@ public class JavaMethodsGenerator { 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()"); + } } } } diff --git a/src/native/common/extgl.h b/src/native/common/extgl.h index b26b92bd..4bec56a7 100644 --- a/src/native/common/extgl.h +++ b/src/native/common/extgl.h @@ -133,6 +133,9 @@ typedef int64_t GLint64; 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_opengl_AMDDebugOutputCallback.c b/src/native/common/org_lwjgl_opengl_AMDDebugOutputCallback.c new file mode 100644 index 00000000..5a23e3e7 --- /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 37ec2fea..81aba5b6 100644 --- a/src/native/linux/context.c +++ b/src/native/linux/context.c @@ -119,6 +119,7 @@ static GLXFBConfig *chooseVisualGLX13FromBPP(JNIEnv *env, Display *disp, int scr 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,9 @@ static GLXFBConfig *chooseVisualGLX13FromBPP(JNIEnv *env, Display *disp, int scr // 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 +202,7 @@ static XVisualInfo *chooseVisualGLXFromBPP(JNIEnv *env, Display *disp, int scree 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 +232,9 @@ static XVisualInfo *chooseVisualGLXFromBPP(JNIEnv *env, Display *disp, int scree // 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 +295,11 @@ bool initPeerInfo(JNIEnv *env, jobject peer_info_handle, Display *display, int s 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 1d8fc6c3..7e07d485 100644 --- a/src/native/linux/extgl_glx.c +++ b/src/native/linux/extgl_glx.c @@ -160,6 +160,7 @@ static void extgl_InitGLXSupportedExtensions(Display *disp, int screen, GLXExten 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 56b98601..0ee85d83 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 @@ typedef struct { 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/windows/context.c b/src/native/windows/context.c index 9665e632..d04adab2 100644 --- a/src/native/windows/context.c +++ b/src/native/windows/context.c @@ -187,6 +187,7 @@ static int findPixelFormatARBFromBPP(JNIEnv *env, HDC hdc, WGLExtensions *extens 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")); @@ -234,7 +235,9 @@ static int findPixelFormatARBFromBPP(JNIEnv *env, HDC hdc, WGLExtensions *extens // 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 +388,7 @@ static int findPixelFormatDefault(JNIEnv *env, HDC hdc, jobject pixel_format, bo 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; @@ -400,6 +403,10 @@ static bool validateAndGetExtensions(JNIEnv *env, WGLExtensions *extensions, HDC 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; + } /* * Apparently, some drivers don't report WGL_ARB_pixel_format_float * even though GL_ARB_color_buffer_float and WGL_ATI_color_format_float @@ -435,6 +442,7 @@ int findPixelFormatOnDC(JNIEnv *env, HDC hdc, int origin_x, int origin_y, jobjec 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 +469,7 @@ int findPixelFormatOnDC(JNIEnv *env, HDC hdc, int origin_x, int origin_y, jobjec // 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 75d8c6ad..b8432b4c 100644 --- a/src/native/windows/extgl_wgl.c +++ b/src/native/windows/extgl_wgl.c @@ -152,6 +152,7 @@ static void extgl_InitSupportedWGLExtensions(WGLExtensions *extensions) { 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 43c06b44..e0ca55be 100644 --- a/src/native/windows/extgl_wgl.h +++ b/src/native/windows/extgl_wgl.h @@ -200,6 +200,15 @@ typedef HDC (APIENTRY * wglGetCurrentReadDCARBPROC) (void); 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 @@ typedef struct { 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/templates/org/lwjgl/opengl/AMD_debug_output.java b/src/templates/org/lwjgl/opengl/AMD_debug_output.java new file mode 100644 index 00000000..13dede0a --- /dev/null +++ b/src/templates/org/lwjgl/opengl/AMD_debug_output.java @@ -0,0 +1,87 @@ +/* + * 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); + + 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 00000000..89094eab --- /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/ARB_texture_buffer_object_rgb32.java b/src/templates/org/lwjgl/opengl/ARB_texture_buffer_object_rgb32.java index 45ed2f3e..31721b4e 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 { } \ No newline at end of file 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 9ea5ab76..0687da10 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/NV_multisample_coverage.java b/src/templates/org/lwjgl/opengl/NV_multisample_coverage.java new file mode 100644 index 00000000..f57fddf8 --- /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