/* * 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; import org.lwjgl.LWJGLException; import org.lwjgl.opengl.*; import java.util.StringTokenizer; import java.util.regex.Pattern; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL32.*; /** * Tests the ARB_create_context extension through the use of the ContextAttribs class. * * @author Spasi */ public final class VersionTest { private VersionTest() { } public static void main(String[] args) { initialize(args); cleanup(); System.exit(0); } private static void initialize(String[] args) { if ( args.length < 2 ) argsError("Insufficient number of arguments"); int majorInput = 1; int minorInput = 0; try { majorInput = Integer.parseInt(args[0]); minorInput = Integer.parseInt(args[1]); } catch (NumberFormatException e) { argsError("Invalid number format"); } ContextAttribs ca = new ContextAttribs(majorInput, minorInput); if ( 2 < args.length ) { for ( int i = 2; i < args.length; i++ ) { if ( "core".equalsIgnoreCase(args[i]) ) ca = ca.withProfileCore(true); else if ( "compatibility".equalsIgnoreCase(args[i]) ) ca = ca.withProfileCompatibility(true); else if ( "es".equalsIgnoreCase(args[i]) ) ca = ca.withProfileES(true); else if ( "debug".equalsIgnoreCase(args[i]) ) ca = ca.withDebug(true); else if ( "fc".equalsIgnoreCase(args[i]) ) ca = ca.withForwardCompatible(true); else if ( "robust".equalsIgnoreCase(args[i]) ) ca = ca.withRobustAccess(true); else if ( "reset_isolation".equalsIgnoreCase(args[i]) ) ca = ca.withContextResetIsolation(true); else if ( "reset_lose".equalsIgnoreCase(args[i]) ) ca = ca.withResetNotificationStrategy(ContextAttribs.LOSE_CONTEXT_ON_RESET_ARB); else if ( "release_none".equalsIgnoreCase(args[i]) ) ca = ca.withContextReleaseBehavior(ContextAttribs.CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); else if ( Pattern.matches("[0-9]+", args[i]) ) ca = ca.withLayer(Integer.parseInt(args[i])); else argsError("Unknown argument: \'" + args[i] + "\'"); } } try { DisplayMode[] modes = Display.getAvailableDisplayModes(); DisplayMode displayMode; 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.create(new PixelFormat(8, 24, 0), ca); } catch (LWJGLException e) { kill(e.getMessage()); } System.out.println("\n---------\n"); System.out.println("Requested " + ca); final String version = glGetString(GL_VERSION); boolean deprecated = false; try { glVertex3f(0.0f, 0.0f, 0.0f); Util.checkGLError(); 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()); final boolean compatibilityProfile; final boolean coreProfile; if ( 3 < majorVersion || (majorVersion == 3 && 2 <= minorVersion) ) { final int profileMask = glGetInteger(GL_CONTEXT_PROFILE_MASK); compatibilityProfile = (profileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0; coreProfile = (profileMask & 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")); } } private static DisplayMode chooseMode(DisplayMode[] modes, int width, int height) { DisplayMode bestMode = null; for ( DisplayMode mode : modes ) { 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() { if ( Display.isCreated() ) Display.destroy(); } private static void argsError(final String msg) { System.out.println("\nInvalid arguments error: " + msg); System.out.println("\nUsage: VersionTest <majorVersion> <minorVersion> {'core'|'compatibility'|'es', 'debug', 'fc', 'robust', 'reset_isolation', 'reset_lose', 'release_none', <layer>}:\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("es\t- Sets the OpenGL ES Profile bit (optional, requires 2.0)."); System.out.println("debug\t- Enables debug mode (optional)."); System.out.println("fc\t- Enables forward compatibility mode (optional, requires 3.0+)."); System.out.println("robust\t- Enables robust access (optional)."); System.out.println("reset_isolation\t- Enables reset isolation (optional)."); System.out.println("reset_lose\t- Enables lose context on reset (optional)."); System.out.println("release_none\t- Enables release behavior = none (optional)."); System.out.println("<layer>\t- Layer plane (optional)."); cleanup(); System.exit(-1); } static void kill(String reason) { System.out.println("The VersionTest program was terminated because an error occured.\n"); System.out.println("Reason: " + (reason == null ? "Unknown" : reason)); cleanup(); System.exit(-1); } }