/* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution 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 Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed or intended for use * in the design, construction, operation or maintenance of any nuclear * facility. */ package javax.media.opengl; import com.jogamp.opengl.impl.DRIHack; import com.jogamp.opengl.impl.Debug; import com.jogamp.opengl.impl.NativeLibLoader; import com.jogamp.nativewindow.impl.NWReflection; import com.jogamp.nativewindow.impl.jvm.JVMUtil; import java.util.HashMap; import java.security.AccessControlContext; import java.security.AccessController; import javax.media.opengl.fixedfunc.GLPointerFunc; /** * Specifies the the OpenGL profile. * * This class static singleton initialization queries the availability of all OpenGL Profiles * and instantiates singleton GLProfile objects for each available profile. * * The platform default profile may be used, using {@link GLProfile#GetProfileDefault()}, * or more specialized versions using the other static GetProfile methods. */ public class GLProfile implements Cloneable { public static final boolean DEBUG = Debug.debug("GLProfile"); // // Public (user-visible) profiles // /** The desktop OpenGL compatibility profile 4.x, with x >= 0, ie GL2 plus GL4.
bc stands for backward compatibility. */ public static final String GL4bc = "GL4bc"; /** The desktop OpenGL core profile 4.x, with x >= 0 */ public static final String GL4 = "GL4"; /** The desktop OpenGL compatibility profile 3.x, with x >= 1, ie GL2 plus GL3.
bc stands for backward compatibility. */ public static final String GL3bc = "GL3bc"; /** The desktop OpenGL core profile 3.x, with x >= 1 */ public static final String GL3 = "GL3"; /** The desktop OpenGL profile 1.x up to 3.0 */ public static final String GL2 = "GL2"; /** The embedded OpenGL profile ES 1.x, with x >= 0 */ public static final String GLES1 = "GLES1"; /** The embedded OpenGL profile ES 2.x, with x >= 0 */ public static final String GLES2 = "GLES2"; /** The intersection of the desktop GL2 and embedded ES1 profile */ public static final String GL2ES1 = "GL2ES1"; /** The intersection of the desktop GL3, GL2 and embedded ES2 profile */ public static final String GL2ES2 = "GL2ES2"; /** The intersection of the desktop GL3 and GL2 profile */ public static final String GL2GL3 = "GL2GL3"; /** * All GL Profiles in the order of default detection: GL2, GL2ES2, GL2ES1, GLES2, GLES1, GL2GL3, GL3 */ public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL2, GL2ES2, GL2ES1, GLES2, GLES1, GL2GL3, GL4bc, GL3bc, GL4, GL3 }; /** * All GL2ES2 Profiles in the order of default detection: GL2ES2, GL2, GLES2, GL3 */ public static final String[] GL_PROFILE_LIST_GL2ES2 = new String[] { GL2ES2, GL2, GLES2, GL4bc, GL3bc, GL4, GL3 }; /** * All GL2ES1 Profiles in the order of default detection: GL2ES1, GL2, GLES1 */ public static final String[] GL_PROFILE_LIST_GL2ES1 = new String[] { GL2ES1, GL2, GLES1 }; /** Returns a default GLProfile object, reflecting the best for the running platform. * It selects the first of the set {@link GLProfile#GL_PROFILE_LIST_ALL} */ public static final GLProfile getDefault() { if(null==defaultGLProfile) { throw new GLException("No default profile available"); // should never be reached } return defaultGLProfile; } /** Returns a GLProfile object. * Verfifies the given profile and chooses an apropriate implementation. * A generic value of null or GL will result in * the default profile. * * @throws GLException if no implementation for the given profile is found. */ public static final GLProfile get(String profile) throws GLException { if(null==profile || profile.equals("GL")) return getDefault(); GLProfile glProfile = (GLProfile) mappedProfiles.get(profile); if(null==glProfile) { throw new GLException("No implementation for profile "+profile+" available"); } return glProfile; } /** * Returns a profile, implementing the interface GL2ES1. * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_GL2ES1} * * @throws GLException if no implementation for the given profile is found. */ public static final GLProfile getGL2ES1() throws GLException { return get(GL_PROFILE_LIST_GL2ES1); } /** * Returns a profile, implementing the interface GL2ES2. * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_GL2ES2} * * @throws GLException if no implementation for the given profile is found. */ public static final GLProfile getGL2ES2() throws GLException { return get(GL_PROFILE_LIST_GL2ES2); } /** * Returns the first profile from the given list, * where an implementation is available. * * @throws GLException if no implementation for the given profile is found. */ public static final GLProfile get(String[] profiles) throws GLException { for(int i=0; imajor || major>=GL_VERSIONS.length) return -1; return GL_VERSIONS[major].length-1; } public static final boolean isValidGLVersion(int major, int minor) { if(1>major || major>=GL_VERSIONS.length) return false; if(0>minor || minor>=GL_VERSIONS[major].length) return false; return true; } public static final boolean decrementGLVersion(int major[], int minor[]) { if(null==major || major.length<1 ||null==minor || minor.length<1) { throw new GLException("invalid array arguments"); } int m = major[0]; int n = minor[0]; if(!isValidGLVersion(m, n)) return false; // decrement .. n -= 1; if(n < 0) { m -= 1; n = GL_VERSIONS[m].length-1; } if(!isValidGLVersion(m, n)) return false; major[0]=m; minor[0]=n; return true; } // The intersection between desktop OpenGL and the union of the OpenGL ES profiles // This is here only to avoid having separate GL2ES1Impl and GL2ES2Impl classes private static final String GL2ES12 = "GL2ES12"; private static final boolean isAWTAvailable; private static final boolean isAWTJOGLAvailable; private static final boolean hasGL4bcImpl; private static final boolean hasGL4Impl; private static final boolean hasGL3bcImpl; private static final boolean hasGL3Impl; private static final boolean hasGL2Impl; private static final boolean hasGL2ES12Impl; private static final boolean hasGLES2Impl; private static final boolean hasGLES1Impl; /** The JVM/process wide default GL profile **/ private static GLProfile defaultGLProfile; /** All GLProfiles */ private static final HashMap/**/ mappedProfiles; /** * Tries the profiles implementation and native libraries. * Throws an GLException if no profile could be found at all. */ static { JVMUtil.initSingleton(); AccessControlContext acc = AccessController.getContext(); isAWTAvailable = !Debug.getBooleanProperty("java.awt.headless", true, acc) && NWReflection.isClassAvailable("java.awt.Component") ; isAWTJOGLAvailable = isAWTAvailable && NWReflection.isClassAvailable("javax.media.nativewindow.awt.AWTGraphicsDevice") && // NativeWindow NWReflection.isClassAvailable("javax.media.opengl.awt.GLCanvas") ; // JOGL boolean hasDesktopGL = false; boolean hasDesktopGLES12 = false; boolean hasNativeOSFactory = false; try { // See DRIHack.java for an explanation of why this is necessary DRIHack.begin(); NativeLibLoader.loadGLDesktop(); DRIHack.end(); hasDesktopGL = true; } catch (Throwable t) { if (DEBUG) { System.err.println("GLProfile.static Desktop GL Library not available"); t.printStackTrace(); } } try { // See DRIHack.java for an explanation of why this is necessary DRIHack.begin(); NativeLibLoader.loadGLDesktopES12(); DRIHack.end(); hasDesktopGLES12 = true; } catch (Throwable t) { if (DEBUG) { System.err.println("GLProfile.static Desktop GL ES12 Library not available"); t.printStackTrace(); } } if(hasDesktopGL||hasDesktopGLES12) { try { hasNativeOSFactory = null!=GLDrawableFactory.getFactoryImpl(GL2); } catch (Throwable t) { if (DEBUG) { System.err.println("GLProfile.static - Native platform GLDrawable factory not available"); t.printStackTrace(); } } } if(!hasNativeOSFactory) { hasDesktopGLES12=false; hasDesktopGL=false; } // FIXME: check for real GL3 availability .. ? hasGL4bcImpl = hasDesktopGL && NWReflection.isClassAvailable("com.jogamp.opengl.impl.gl4.GL4bcImpl"); hasGL4Impl = hasDesktopGL && NWReflection.isClassAvailable("com.jogamp.opengl.impl.gl4.GL4Impl"); hasGL3bcImpl = hasDesktopGL && NWReflection.isClassAvailable("com.jogamp.opengl.impl.gl3.GL3bcImpl"); hasGL3Impl = hasDesktopGL && NWReflection.isClassAvailable("com.jogamp.opengl.impl.gl3.GL3Impl"); hasGL2Impl = hasDesktopGL && NWReflection.isClassAvailable("com.jogamp.opengl.impl.gl2.GL2Impl"); hasGL2ES12Impl = hasDesktopGLES12 && NWReflection.isClassAvailable("com.jogamp.opengl.impl.gl2es12.GL2ES12Impl"); boolean btest = false; boolean hasEGLDynLookup = NWReflection.isClassAvailable("com.jogamp.opengl.impl.egl.EGLDynamicLookupHelper"); boolean hasEGLDrawableFactory = false; try { if(hasEGLDynLookup) { hasEGLDrawableFactory = null!=GLDrawableFactory.getFactoryImpl(GLES2); btest = hasEGLDrawableFactory && NWReflection.isClassAvailable("com.jogamp.opengl.impl.es2.GLES2Impl") && null!=com.jogamp.opengl.impl.egl.EGLDynamicLookupHelper.getDynamicLookupHelper(2); } } catch (Throwable t) { if (DEBUG) { System.err.println("GLProfile.static - GL ES2 Factory/Library not available"); t.printStackTrace(); } } hasGLES2Impl = btest; btest = false; try { if(hasEGLDynLookup) { btest = hasEGLDrawableFactory && NWReflection.isClassAvailable("com.jogamp.opengl.impl.es1.GLES1Impl") && null!=com.jogamp.opengl.impl.egl.EGLDynamicLookupHelper.getDynamicLookupHelper(1); } } catch (Throwable t) { if (DEBUG) { System.err.println("GLProfile.static - GL ES1 Factory/Library not available"); t.printStackTrace(); } } hasGLES1Impl = btest; if (DEBUG) { System.err.println("GLProfile.static isAWTAvailable "+isAWTAvailable); System.err.println("GLProfile.static isAWTJOGLAvailable "+isAWTJOGLAvailable); System.err.println("GLProfile.static hasNativeOSFactory "+hasNativeOSFactory); System.err.println("GLProfile.static hasDesktopGLES12 "+hasDesktopGLES12); System.err.println("GLProfile.static hasDesktopGL "+hasDesktopGL); System.err.println("GLProfile.static hasGL4bcImpl "+hasGL4bcImpl); System.err.println("GLProfile.static hasGL4Impl "+hasGL4Impl); System.err.println("GLProfile.static hasGL3bcImpl "+hasGL3bcImpl); System.err.println("GLProfile.static hasGL3Impl "+hasGL3Impl); System.err.println("GLProfile.static hasGL2Impl "+hasGL2Impl); System.err.println("GLProfile.static hasGL2ES12Impl "+hasGL2ES12Impl); System.err.println("GLProfile.static hasEGLDynLookup "+hasEGLDynLookup); System.err.println("GLProfile.static hasEGLDrawableFactory "+hasEGLDrawableFactory); System.err.println("GLProfile.static hasGLES2Impl "+hasGLES2Impl); System.err.println("GLProfile.static hasGLES1Impl "+hasGLES1Impl); } HashMap/**/ _mappedProfiles = new HashMap(GL_PROFILE_LIST_ALL.length); for(int i=0; i 0) msg.append(", "); msg.append(list[i]); } msg.append("]"); return msg.toString(); } /** * Returns the profile implementation */ private static String computeProfileImpl(String profile) { // FIXME Order of return profiles, after we can test their availability if (GL2ES1.equals(profile)) { if(hasGL2ES12Impl) { return GL2ES12; } else if(hasGL2Impl) { return GL2; } else if(hasGLES1Impl) { return GLES1; } } else if (GL2ES2.equals(profile)) { if(hasGL2ES12Impl) { return GL2ES12; } else if(hasGL2Impl) { return GL2; } else if(hasGL3Impl) { return GL3; } else if(hasGL3bcImpl) { return GL3bc; } else if(hasGL4Impl) { return GL4; } else if(hasGL4bcImpl) { return GL4bc; } else if(hasGLES2Impl) { return GLES2; } } else if(GL4bc.equals(profile) && hasGL4bcImpl) { return GL4bc; } else if(GL4.equals(profile)) { if(hasGL4Impl) { return GL4; } else if(hasGL4bcImpl) { return GL4bc; } } else if(GL3bc.equals(profile) && hasGL3bcImpl) { return GL3bc; } else if(GL3.equals(profile)) { if(hasGL3Impl) { return GL3; } else if(hasGL3bcImpl) { return GL3bc; } } else if(GL2.equals(profile) && hasGL2Impl) { return GL2; } else if(GL2GL3.equals(profile) && hasGL2Impl) { return GL2; } else if(GLES2.equals(profile) && hasGLES2Impl) { return GLES2; } else if(GLES1.equals(profile) && hasGLES1Impl) { return GLES1; } return null; } public static boolean isAWTAvailable() { return isAWTAvailable; } public static boolean isAWTJOGLAvailable() { return isAWTJOGLAvailable; } public static String getGLTypeName(int type) { switch (type) { case GL.GL_UNSIGNED_BYTE: return "GL_UNSIGNED_BYTE"; case GL.GL_BYTE: return "GL_BYTE"; case GL.GL_UNSIGNED_SHORT: return "GL_UNSIGNED_SHORT"; case GL.GL_SHORT: return "GL_SHORT"; case GL.GL_FLOAT: return "GL_FLOAT"; case GL.GL_FIXED: return "GL_FIXED"; case javax.media.opengl.GL2ES2.GL_INT: return "GL_INT"; case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT: return "GL_UNSIGNED_INT"; case javax.media.opengl.GL2.GL_DOUBLE: return "GL_DOUBLE"; case javax.media.opengl.GL2.GL_2_BYTES: return "GL_2_BYTES"; case javax.media.opengl.GL2.GL_3_BYTES: return "GL_3_BYTES"; case javax.media.opengl.GL2.GL_4_BYTES: return "GL_4_BYTES"; } return null; } public static String getGLArrayName(int array) { switch(array) { case GLPointerFunc.GL_VERTEX_ARRAY: return "GL_VERTEX_ARRAY"; case GLPointerFunc.GL_NORMAL_ARRAY: return "GL_NORMAL_ARRAY"; case GLPointerFunc.GL_COLOR_ARRAY: return "GL_COLOR_ARRAY"; case GLPointerFunc.GL_TEXTURE_COORD_ARRAY: return "GL_TEXTURE_COORD_ARRAY"; } return null; } private GLProfile(String profile, String profileImpl) { this.profile = profile; this.profileImpl = profileImpl; } private String profileImpl = null; private String profile = null; }