diff options
author | Sven Gothel <[email protected]> | 2010-04-16 03:51:00 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-04-16 03:51:00 +0200 |
commit | bb028021be2714e66d9b1062298a3e308c649c56 (patch) | |
tree | d20a568ae0d7da2b9f600464a5bc18d88edb1b89 | |
parent | bd4904fb04ab2168aeaf76e74385b3991429289a (diff) |
JOGL GL4 preperation:
- Re-Enable GL3bc native library build, works ..
- Adding all the is/get GL4/GL4bc stubs ..
- Adding dummy interface GL4 and GL4bc, will be removed when done
- Context creation refactoring:
- Move Version information to GLContext
- Determine version by creation if possible (ARB_create_context),
only use the unreliable GL_VERSION string if necessary.
- Offering an almost platform independent ARB_create_context path:
- createContextARBImpl - platform dependent GLX calls
- createContextARB - platform independent setup and version loop
27 files changed, 826 insertions, 413 deletions
diff --git a/make/build-jogl.xml b/make/build-jogl.xml index 93cf7bf6f..d42b859bd 100644 --- a/make/build-jogl.xml +++ b/make/build-jogl.xml @@ -946,7 +946,7 @@ <!-- Perform the first pass Java compile. --> <javac destdir="${classes}" - includes="javax/media/opengl/fixedfunc/** javax/media/opengl/GLDrawableFactory.java javax/media/opengl/GLDrawable.java javax/media/opengl/GLContext.java javax/media/opengl/GL.java javax/media/opengl/GL2ES1.java javax/media/opengl/GL2ES2.java javax/media/opengl/GL2GL3.java javax/media/opengl/GL2.java javax/media/opengl/GLES1.java javax/media/opengl/GLES2.java javax/media/opengl/GL3.java javax/media/opengl/GL3bc.java" + includes="javax/media/opengl/fixedfunc/** javax/media/opengl/GLDrawableFactory.java javax/media/opengl/GLDrawable.java javax/media/opengl/GLContext.java javax/media/opengl/GL.java javax/media/opengl/GL2ES1.java javax/media/opengl/GL2ES2.java javax/media/opengl/GL2GL3.java javax/media/opengl/GL2.java javax/media/opengl/GLES1.java javax/media/opengl/GLES2.java javax/media/opengl/GL3.java javax/media/opengl/GL3bc.java javax/media/opengl/GL4.java javax/media/opengl/GL4bc.java" fork="yes" memoryMaximumSize="${javac.memorymax}" includeAntRuntime="false" @@ -1261,6 +1261,7 @@ <include name="${rootrel.generated.c.jogl}/gl2/GL2Impl_JNI.c"/> <include name="${rootrel.generated.c.jogl}/gl3/GL3Impl_JNI.c"/> + <include name="${rootrel.generated.c.jogl}/gl3/GL3bcImpl_JNI.c"/> <!--include name="${rootrel.generated.c.jogl}/GLU_JNI.c"/ EMPTY --> <include name="${rootrel.generated.c.jogl}/gl2/GLUgl2_JNI.c"/> <include name="${rootrel.generated.c.jogl}/X11/GLX*.c" if="isX11"/> diff --git a/make/config/jogl/gl-common.cfg b/make/config/jogl/gl-common.cfg index 0f6529167..8d726c4bf 100644 --- a/make/config/jogl/gl-common.cfg +++ b/make/config/jogl/gl-common.cfg @@ -388,8 +388,12 @@ ArgumentIsString glTransformFeedbackVaryings 2 # Use cached GL_EXTENSION if possible, # which also allows GL3 compatibility. # -JavaPrologue glGetString if(GL.GL_EXTENSIONS==name && _context.isExtensionCacheInitialized()) { -JavaPrologue glGetString return _context.getGLExtensions(); +JavaPrologue glGetString if(_context.isExtensionCacheInitialized()) { +JavaPrologue glGetString if(GL.GL_EXTENSIONS==name) { +JavaPrologue glGetString return _context.getGLExtensions(); +JavaPrologue glGetString } /* else if(GL.GL_VERSION==name) { +JavaPrologue glGetString return _context.getGLVersion(); +JavaPrologue glGetString } */ JavaPrologue glGetString } # diff --git a/make/config/jogl/gl-gl3bc.cfg b/make/config/jogl/gl-gl3bc.cfg index a637df941..7bba2f635 100644 --- a/make/config/jogl/gl-gl3bc.cfg +++ b/make/config/jogl/gl-gl3bc.cfg @@ -83,6 +83,7 @@ CustomJavaCode GL3bcImpl public void glDepthRangef(float zNear, float zFar) { CustomJavaCode GL3bcImpl glDepthRange((double)zNear, (double)zFar); } Include gl-headers.cfg +Include gl3ext-headers.cfg Include ../intptr.cfg IncludeAs CustomJavaCode GL3bcImpl gl-impl-CustomJavaCode-common.java diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl2.java b/make/config/jogl/gl-impl-CustomJavaCode-gl2.java index cd1a24459..0658b8a01 100644 --- a/make/config/jogl/gl-impl-CustomJavaCode-gl2.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gl2.java @@ -28,6 +28,14 @@ public final boolean isGL() { return true; } +public final boolean isGL4bc() { + return false; +} + +public final boolean isGL4() { + return false; +} + public final boolean isGL3bc() { return false; } @@ -72,6 +80,14 @@ public final GL getGL() throws GLException { return this; } +public final GL4bc getGL4bc() throws GLException { + throw new GLException("Not a GL4bc implementation"); +} + +public final GL4 getGL4() throws GLException { + throw new GLException("Not a GL4 implementation"); +} + public final GL3bc getGL3bc() throws GLException { throw new GLException("Not a GL3bc implementation"); } diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl2es12.java b/make/config/jogl/gl-impl-CustomJavaCode-gl2es12.java index 2eca2b6ab..54c7bd92b 100644 --- a/make/config/jogl/gl-impl-CustomJavaCode-gl2es12.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gl2es12.java @@ -30,6 +30,14 @@ public final boolean isGL() { return true; } +public final boolean isGL4bc() { + return false; +} + +public final boolean isGL4() { + return false; +} + public final boolean isGL3bc() { return false; } @@ -74,6 +82,14 @@ public final GL getGL() throws GLException { return this; } +public final GL4bc getGL4bc() throws GLException { + throw new GLException("Not a GL4bc implementation"); +} + +public final GL4 getGL4() throws GLException { + throw new GLException("Not a GL4 implementation"); +} + public final GL3bc getGL3bc() throws GLException { throw new GLException("Not a GL3bc implementation"); } diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl3.java b/make/config/jogl/gl-impl-CustomJavaCode-gl3.java index 16ff008cf..cff0b0f94 100644 --- a/make/config/jogl/gl-impl-CustomJavaCode-gl3.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gl3.java @@ -27,6 +27,14 @@ public final boolean isGL() { return true; } +public final boolean isGL4bc() { + return false; +} + +public final boolean isGL4() { + return false; +} + public final boolean isGL3bc() { return false; } @@ -71,6 +79,14 @@ public final GL getGL() throws GLException { return this; } +public final GL4bc getGL4bc() throws GLException { + throw new GLException("Not a GL4bc implementation"); +} + +public final GL4 getGL4() throws GLException { + throw new GLException("Not a GL4 implementation"); +} + public final GL3bc getGL3bc() throws GLException { throw new GLException("Not a GL3bc implementation"); } diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl3bc.java b/make/config/jogl/gl-impl-CustomJavaCode-gl3bc.java index 2b7f14918..2f804a218 100644 --- a/make/config/jogl/gl-impl-CustomJavaCode-gl3bc.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gl3bc.java @@ -28,6 +28,14 @@ public final boolean isGL() { return true; } +public final boolean isGL4bc() { + return false; +} + +public final boolean isGL4() { + return false; +} + public final boolean isGL3bc() { return true; } @@ -72,6 +80,14 @@ public final GL getGL() throws GLException { return this; } +public final GL4bc getGL4bc() throws GLException { + throw new GLException("Not a GL4bc implementation"); +} + +public final GL4 getGL4() throws GLException { + throw new GLException("Not a GL4 implementation"); +} + public final GL3bc getGL3bc() throws GLException { return this; } diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java index dfef10ec9..6fb8a32ef 100755 --- a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java @@ -10,6 +10,14 @@ public final boolean isGL() { return true; } +public final boolean isGL4bc() { + return false; +} + +public final boolean isGL4() { + return false; +} + public final boolean isGL3bc() { return false; } @@ -54,6 +62,14 @@ public final GL getGL() throws GLException { return this; } +public final GL4bc getGL4bc() throws GLException { + throw new GLException("Not a GL4bc implementation"); +} + +public final GL4 getGL4() throws GLException { + throw new GLException("Not a GL4 implementation"); +} + public final GL3bc getGL3bc() throws GLException { throw new GLException("Not a GL3bc implementation"); } diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java index 7287408a0..8204bd1ae 100755 --- a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java +++ b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java @@ -14,6 +14,14 @@ public final boolean isGL() { return true; } +public final boolean isGL4bc() { + return false; +} + +public final boolean isGL4() { + return false; +} + public final boolean isGL3bc() { return false; } @@ -58,6 +66,14 @@ public final GL getGL() throws GLException { return this; } +public final GL4bc getGL4bc() throws GLException { + throw new GLException("Not a GL4bc implementation"); +} + +public final GL4 getGL4() throws GLException { + throw new GLException("Not a GL4 implementation"); +} + public final GL3bc getGL3bc() throws GLException { throw new GLException("Not a GL3bc implementation"); } diff --git a/make/config/jogl/gl3ext-headers.cfg b/make/config/jogl/gl3ext-headers.cfg new file mode 100755 index 000000000..dfc4ea796 --- /dev/null +++ b/make/config/jogl/gl3ext-headers.cfg @@ -0,0 +1,5 @@ +CustomCCode /* Define GL_GL3EXT_PROTOTYPES so that the OpenGL extension prototypes in +CustomCCode "gl3ext.h" are parsed. */ +CustomCCode #define GL_GL3EXT_PROTOTYPES +CustomCCode #include <GL3/gl3ext.h> +CustomCCode #include <GL3/gl3ext.h> diff --git a/src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java b/src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java index f36c4f749..082f006e8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java @@ -66,12 +66,10 @@ public final class ExtensionAvailabilityCache { public void flush() { if(DEBUG) { - System.out.println("ExtensionAvailabilityCache: Flush availability OpenGL "+majorVersion+"."+minorVersion); + System.out.println("ExtensionAvailabilityCache: Flush availability OpenGL "+context.getGLVersion()); } availableExtensionCache.clear(); initialized = false; - majorVersion = 1; - minorVersion = 0; } /** @@ -104,53 +102,23 @@ public final class ExtensionAvailabilityCache { return glExtensions; } - public int getMajorVersion() { - initAvailableExtensions(); - return majorVersion; - } - - public int getMinorVersion() { - initAvailableExtensions(); - return minorVersion; - } - private void initAvailableExtensions() { + GL gl = context.getGL(); // if hash is empty (meaning it was flushed), pre-cache it with the list // of extensions that are in the GL_EXTENSIONS string if (availableExtensionCache.isEmpty() || !initialized) { - GL gl = context.getGL(); - if (DEBUG) { - System.err.println("ExtensionAvailabilityCache: Pre-caching init "+gl+", GL_VERSION "+gl.glGetString(GL.GL_VERSION)); - } - - // Set version - Version version = new Version(gl.glGetString(GL.GL_VERSION)); - if (version.isValid()) { - majorVersion = version.getMajor(); - minorVersion = version.getMinor(); - - if( !gl.isGL3() && - ( majorVersion > 3 || - ( majorVersion == 3 && minorVersion >= 1 ) ) ) { - // downsize version to 3.0 in case we are not using GL3 (3.1) - majorVersion = 3; - minorVersion = 0; - } + System.err.println("ExtensionAvailabilityCache: Pre-caching init "+gl+", OpenGL "+context.getGLVersion()); } boolean useGetStringi = false; - if ( majorVersion > 3 || - ( majorVersion == 3 && minorVersion >= 0 ) || + if ( context.getGLVersionMajor() > 3 || + ( context.getGLVersionMajor() == 3 && context.getGLVersionMinor() >= 0 ) || gl.isGL3() ) { - if ( ! gl.isGL2GL3() ) { + if ( ! gl.isFunctionAvailable("glGetStringi") ) { if(DEBUG) { - System.err.println("ExtensionAvailabilityCache: GL >= 3.1 usage, but no GL2GL3 interface: "+gl.getClass().getName()); - } - } else if ( ! gl.isFunctionAvailable("glGetStringi") ) { - if(DEBUG) { - System.err.println("ExtensionAvailabilityCache: GL >= 3.1 usage, but no glGetStringi"); + System.err.println("GLContext: GL >= 3.1 usage, but no glGetStringi"); } } else { useGetStringi = true; @@ -158,7 +126,7 @@ public final class ExtensionAvailabilityCache { } if (DEBUG) { - System.err.println("ExtensionAvailabilityCache: Pre-caching extension availability OpenGL "+majorVersion+"."+minorVersion+ + System.err.println("ExtensionAvailabilityCache: Pre-caching extension availability OpenGL "+context.getGLVersion()+ ", use "+ ( useGetStringi ? "glGetStringi" : "glGetString" ) ); } @@ -197,39 +165,21 @@ public final class ExtensionAvailabilityCache { } } - // Put GL version strings in the table as well - // FIXME: this needs to be adjusted when the major rev changes - // beyond the known ones - int major = majorVersion; - int minor = minorVersion; - while (major > 0) { - while (minor >= 0) { - availableExtensionCache.add("GL_VERSION_" + major + "_" + minor); - if (DEBUG) { - System.err.println("ExtensionAvailabilityCache: Added GL_VERSION_" + major + "_" + minor + " to known extensions"); - } - --minor; - } - - switch (major) { - case 3: - if(gl.isGL3()) { - // GL3 is a GL 3.1 forward compatible context, - // hence no 2.0, 1.0 - 1.5 GL versions are supported. - major=0; - } - // Restart loop at version 2.1 - minor = 1; - break; - case 2: - // Restart loop at version 1.5 - minor = 5; - break; - case 1: - break; + int major[] = new int[] { context.getGLVersionMajor() }; + int minor[] = new int[] { context.getGLVersionMinor() }; + if( !gl.isGL3() && !gl.isGL4() && + ( major[0] > 3 || + ( major[0] == 3 && minor[0] >= 1 ) ) ) { + // downsize version to 3.0 in case we are not using GL3 (>=3.1) + major[0] = 3; + minor[0] = 0; + } + while (GLProfile.isValidGLVersion(major[0], minor[0])) { + availableExtensionCache.add("GL_VERSION_" + major[0] + "_" + minor[0]); + if (DEBUG) { + System.err.println("ExtensionAvailabilityCache: Added GL_VERSION_" + major[0] + "_" + minor[0] + " to known extensions"); } - - --major; + if(!GLProfile.decrementGLVersion(major, minor)) break; } // put a dummy var in here so that the cache is no longer empty even if @@ -255,136 +205,9 @@ public final class ExtensionAvailabilityCache { // private boolean initialized = false; - private int majorVersion = 1; - private int minorVersion = 0; private String glExtensions = null; private String glXExtensions = null; private HashSet availableExtensionCache = new HashSet(50); private GLContextImpl context; - /** - * A class for storing and comparing OpenGL version numbers. - * This only works for desktop OpenGL at the moment. - */ - private static class Version implements Comparable - { - private boolean valid; - private int major, minor, sub; - public Version(int majorRev, int minorRev, int subMinorRev) - { - major = majorRev; - minor = minorRev; - sub = subMinorRev; - } - - /** - * @param versionString must be of the form "GL_VERSION_X" or - * "GL_VERSION_X_Y" or "GL_VERSION_X_Y_Z" or "X.Y", where X, Y, - * and Z are integers. - * - * @exception IllegalArgumentException if the argument is not a valid - * OpenGL version identifier - */ - public Version(String versionString) - { - try - { - if (versionString.startsWith("GL_VERSION_")) - { - StringTokenizer tok = new StringTokenizer(versionString, "_"); - - tok.nextToken(); // GL_ - tok.nextToken(); // VERSION_ - if (!tok.hasMoreTokens()) { major = 0; return; } - major = Integer.valueOf(tok.nextToken()).intValue(); - if (!tok.hasMoreTokens()) { minor = 0; return; } - minor = Integer.valueOf(tok.nextToken()).intValue(); - if (!tok.hasMoreTokens()) { sub = 0; return; } - sub = Integer.valueOf(tok.nextToken()).intValue(); - } - else - { - int radix = 10; - if (versionString.length() > 2) { - if (Character.isDigit(versionString.charAt(0)) && - versionString.charAt(1) == '.' && - Character.isDigit(versionString.charAt(2))) { - major = Character.digit(versionString.charAt(0), radix); - minor = Character.digit(versionString.charAt(2), radix); - - // See if there's version-specific information which might - // imply a more recent OpenGL version - StringTokenizer tok = new StringTokenizer(versionString, " "); - if (tok.hasMoreTokens()) { - tok.nextToken(); - if (tok.hasMoreTokens()) { - String token = tok.nextToken(); - int i = 0; - while (i < token.length() && !Character.isDigit(token.charAt(i))) { - i++; - } - if (i < token.length() - 2 && - Character.isDigit(token.charAt(i)) && - token.charAt(i+1) == '.' && - Character.isDigit(token.charAt(i+2))) { - int altMajor = Character.digit(token.charAt(i), radix); - int altMinor = Character.digit(token.charAt(i+2), radix); - // Avoid possibly confusing situations by putting some - // constraints on the upgrades we do to the major and - // minor versions - if ((altMajor == major && altMinor > minor) || - altMajor == major + 1) { - major = altMajor; - minor = altMinor; - } - } - } - } - } - } - } - valid = true; - } - catch (Exception e) - { - // FIXME: refactor desktop OpenGL dependencies and make this - // class work properly for OpenGL ES - System.err.println("ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: "+e); - major = 1; - minor = 0; - /* - throw (IllegalArgumentException) - new IllegalArgumentException( - "Illegally formatted version identifier: \"" + versionString + "\"") - .initCause(e); - */ - } - } - - public boolean isValid() { - return valid; - } - - public int compareTo(Object o) - { - Version vo = (Version)o; - if (major > vo.major) return 1; - else if (major < vo.major) return -1; - else if (minor > vo.minor) return 1; - else if (minor < vo.minor) return -1; - else if (sub > vo.sub) return 1; - else if (sub < vo.sub) return -1; - - return 0; // they are equal - } - - public int getMajor() { - return major; - } - - public int getMinor() { - return minor; - } - - } // end class Version } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java index 7543a1084..8c5890d1e 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java @@ -44,6 +44,7 @@ import java.nio.*; import java.util.*; import javax.media.opengl.*; +import javax.media.nativewindow.*; import com.jogamp.nativewindow.impl.NWReflection; import com.jogamp.gluegen.runtime.*; import com.jogamp.gluegen.runtime.opengl.*; @@ -122,6 +123,108 @@ public abstract class GLContextImpl extends GLContext { return (GLDrawableImpl) getGLDrawable(); } + /** + * Platform dependent but harmonized implementation of the <code>ARB_create_context</code> + * mechanism to create a context.<br> + * The implementation shall verify this context, ie issue a + * <code>MakeCurrent</code> call if necessary.<br> + * + * @param share the shared context or null + * @param direct flag if direct is requested + * @param ctxOptionFlags <code>ARB_create_context</code> related, see references below + * @param major major number + * @param minor minor number + * @return the valid context if successfull, or null + * + * @see #CTX_PROFILE_COMPAT + * @see #CTX_OPTION_FORWARD + * @see #CTX_OPTION_DEBUG + */ + protected abstract long createContextARBImpl(long share, boolean direct, int ctxOptionFlags, + int major, int minor); + + private long createContextARB(long share, boolean direct, int ctxOptionFlags, + int majorMax, int minorMax, + int majorMin, int minorMin, + int major[], int minor[]) { + major[0]=majorMax; + minor[0]=minorMax; + long _context=0; + + while ( 0==_context && + GLProfile.isValidGLVersion(major[0], minor[0]) && + ( major[0]>majorMin || major[0]==majorMin && minor[0] >=minorMin ) ) { + + _context = createContextARBImpl(share, direct, ctxOptionFlags, major[0], minor[0]); + + if(0==_context) { + if(!GLProfile.decrementGLVersion(major, minor)) break; + } + } + return _context; + } + + /** + * Platform independent part of using the <code>ARB_create_context</code> + * mechanism to create a context.<br> + */ + protected long createContextARB(long share, boolean direct, + int major[], int minor[], int ctp[]) + { + AbstractGraphicsConfiguration config = drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities(); + GLProfile glp = glCaps.getGLProfile(); + long _context = 0; + + ctp[0] = CTX_IS_ARB_CREATED | CTX_PROFILE_CORE | CTX_OPTION_ANY; // default + boolean isBackwardCompatibility = glp.isGL2() || glp.isGL3bc() || glp.isGL4bc() ; + int majorMin, minorMin; + int majorMax, minorMax; + if( glp.isGL4() ) { + // ?? majorMax=GLProfile.getMaxMajor(); minorMax=GLProfile.getMaxMinor(majorMax); + majorMax=4; minorMax=GLProfile.getMaxMinor(majorMax); + majorMin=4; minorMin=0; + } else if( glp.isGL3() ) { + majorMax=3; minorMax=GLProfile.getMaxMinor(majorMax); + majorMin=3; minorMin=1; + } else /* if( glp.isGL2() ) */ { + majorMax=3; minorMax=0; + majorMin=1; minorMin=1; // our minimum desktop OpenGL runtime requirements + } + // Try the requested .. + if(isBackwardCompatibility) { + ctp[0] &= ~CTX_PROFILE_CORE ; + ctp[0] |= CTX_PROFILE_COMPAT ; + } + _context = createContextARB(share, direct, ctp[0], + /* max */ majorMax, minorMax, + /* min */ majorMin, minorMin, + /* res */ major, minor); + + if(0==_context && !isBackwardCompatibility) { + ctp[0] &= ~CTX_PROFILE_COMPAT ; + ctp[0] |= CTX_PROFILE_CORE ; + ctp[0] &= ~CTX_OPTION_ANY ; + ctp[0] |= CTX_OPTION_FORWARD ; + _context = createContextARB(share, direct, ctp[0], + /* max */ majorMax, minorMax, + /* min */ majorMin, minorMin, + /* res */ major, minor); + if(0==_context) { + // Try a compatible one .. even though not requested .. last resort + ctp[0] &= ~CTX_PROFILE_CORE ; + ctp[0] |= CTX_PROFILE_COMPAT ; + ctp[0] &= ~CTX_OPTION_FORWARD ; + ctp[0] |= CTX_OPTION_ANY ; + _context = createContextARB(share, direct, ctp[0], + /* max */ majorMax, minorMax, + /* min */ majorMin, minorMin, + /* res */ major, minor); + } + } + return _context; + } + public int makeCurrent() throws GLException { // Support calls to makeCurrent() over and over again with // different contexts without releasing them @@ -272,7 +375,7 @@ public abstract class GLContextImpl extends GLContext { if(DEBUG) { String sgl1 = (null!=this.gl)?this.gl.getClass().toString()+", "+this.gl.toString():new String("<null>"); String sgl2 = (null!=gl)?gl.getClass().toString()+", "+gl.toString():new String("<null>"); - Exception e = new Exception("setGL: "+Thread.currentThread()+", "+sgl1+" -> "+sgl2); + Exception e = new Exception("setGL (OpenGL "+getGLVersion()+"): "+Thread.currentThread()+", "+sgl1+" -> "+sgl2); e.printStackTrace(); } this.gl = gl; @@ -282,6 +385,77 @@ public abstract class GLContextImpl extends GLContext { public abstract Object getPlatformGLExtensions(); //---------------------------------------------------------------------- + // Managing the actual OpenGL version, usually figured at creation time. + // As a last resort, the GL_VERSION string may be used .. + // + + /** + * If major > 0 || minor > 0 : Use passed values, determined at creation time + * If major==0 && minor == 0 : Use GL_VERSION + * Otherwise .. don't touch .. + */ + protected void setContextVersion(int major, int minor, int ctp) { + if(major>0 || minor>0) { + ctxMajorVersion = major; + ctxMinorVersion = minor; + ctxOptions = ctp; + ctxVersionString = getGLVersion(gl, ctxMajorVersion, ctxMinorVersion, ctxOptions, getGL().glGetString(GL.GL_VERSION)); + return; + } + + if(major==0 && minor==0) { + String versionStr = getGL().glGetString(GL.GL_VERSION); + if(null==versionStr) { + throw new GLException("GL_VERSION is NULL: "+this); + } + + // Set version + Version version = new Version(versionStr); + if (version.isValid()) { + ctxMajorVersion = version.getMajor(); + ctxMinorVersion = version.getMinor(); + + ctxVersionString = getGLVersion(gl, ctxMajorVersion, ctxMinorVersion, ctxOptions, versionStr); + return; + } + } + } + + private static boolean appendString(StringBuffer sb, String string, boolean needColon, boolean condition) { + if(condition) { + if(needColon) { + sb.append(", "); + } + sb.append(string); + needColon=true; + } + return needColon; + } + + protected static String getGLVersion(GL gl, int major, int minor, int ctp, String gl_version) { + boolean needColon = false; + StringBuffer sb = new StringBuffer(); + sb.append(major); + sb.append("."); + sb.append(minor); + sb.append(" ("); + needColon = appendString(sb, "ES", needColon, null!=gl && gl.isGLES()); + needColon = appendString(sb, "compatibility profile", needColon, 0 != ( CTX_PROFILE_COMPAT & ctp )); + needColon = appendString(sb, "core profile", needColon, 0 != ( CTX_PROFILE_CORE & ctp )); + needColon = appendString(sb, "forward compatible", needColon, 0 != ( CTX_OPTION_FORWARD & ctp )); + needColon = appendString(sb, "any", needColon, 0 != ( CTX_OPTION_ANY & ctp )); + needColon = appendString(sb, "new", needColon, 0 != ( CTX_IS_ARB_CREATED & ctp )); + needColon = appendString(sb, "old", needColon, 0 == ( CTX_IS_ARB_CREATED & ctp )); + sb.append(") - "); + if(null!=gl_version) { + sb.append(gl_version); + } else { + sb.append("n/a"); + } + return sb.toString(); + } + + //---------------------------------------------------------------------- // Helpers for various context implementations // @@ -391,8 +565,10 @@ public abstract class GLContextImpl extends GLContext { * * @param force force the setting, even if is already being set. * This might be usefull if you change the OpenGL implementation. + * + * @see #setContextVersion */ - protected void setGLFunctionAvailability(boolean force) { + protected void setGLFunctionAvailability(boolean force, int major, int minor, int ctp) { if(null!=this.gl && null!=glProcAddressTable && !force) { return; // already done and not forced } @@ -400,15 +576,17 @@ public abstract class GLContextImpl extends GLContext { setGL(createGL(getGLDrawable().getGLProfile())); } - updateGLProcAddressTable(); + updateGLProcAddressTable(major, minor, ctp); } /** * Updates the cache of which GL functions are available for calling through this * context. See {@link #isFunctionAvailable(String)} for more information on * the definition of "available". + * + * @see #setContextVersion */ - protected void updateGLProcAddressTable() { + protected void updateGLProcAddressTable(int major, int minor, int ctp) { if(null==this.gl) { throw new GLException("setGLFunctionAvailability not called yet"); } @@ -422,6 +600,8 @@ public abstract class GLContextImpl extends GLContext { } resetProcAddressTable(getGLProcAddressTable()); + setContextVersion(major, minor, ctp); + extensionAvailability.reset(); } @@ -493,14 +673,6 @@ public abstract class GLContextImpl extends GLContext { return extensionAvailability.getGLExtensions(); } - public int getMajorVersion() { - return extensionAvailability.getMajorVersion(); - } - - public int getMinorVersion() { - return extensionAvailability.getMinorVersion(); - } - public boolean isExtensionCacheInitialized() { return extensionAvailability.isInitialized(); } @@ -617,4 +789,131 @@ public abstract class GLContextImpl extends GLContext { */ + /** + * A class for storing and comparing OpenGL version numbers. + * This only works for desktop OpenGL at the moment. + */ + private static class Version implements Comparable + { + private boolean valid; + private int major, minor, sub; + public Version(int majorRev, int minorRev, int subMinorRev) + { + major = majorRev; + minor = minorRev; + sub = subMinorRev; + } + + /** + * @param versionString must be of the form "GL_VERSION_X" or + * "GL_VERSION_X_Y" or "GL_VERSION_X_Y_Z" or "X.Y", where X, Y, + * and Z are integers. + * + * @exception IllegalArgumentException if the argument is not a valid + * OpenGL version identifier + */ + public Version(String versionString) + { + try + { + if (versionString.startsWith("GL_VERSION_")) + { + StringTokenizer tok = new StringTokenizer(versionString, "_"); + + tok.nextToken(); // GL_ + tok.nextToken(); // VERSION_ + if (!tok.hasMoreTokens()) { major = 0; return; } + major = Integer.valueOf(tok.nextToken()).intValue(); + if (!tok.hasMoreTokens()) { minor = 0; return; } + minor = Integer.valueOf(tok.nextToken()).intValue(); + if (!tok.hasMoreTokens()) { sub = 0; return; } + sub = Integer.valueOf(tok.nextToken()).intValue(); + } + else + { + int radix = 10; + if (versionString.length() > 2) { + if (Character.isDigit(versionString.charAt(0)) && + versionString.charAt(1) == '.' && + Character.isDigit(versionString.charAt(2))) { + major = Character.digit(versionString.charAt(0), radix); + minor = Character.digit(versionString.charAt(2), radix); + + // See if there's version-specific information which might + // imply a more recent OpenGL version + StringTokenizer tok = new StringTokenizer(versionString, " "); + if (tok.hasMoreTokens()) { + tok.nextToken(); + if (tok.hasMoreTokens()) { + String token = tok.nextToken(); + int i = 0; + while (i < token.length() && !Character.isDigit(token.charAt(i))) { + i++; + } + if (i < token.length() - 2 && + Character.isDigit(token.charAt(i)) && + token.charAt(i+1) == '.' && + Character.isDigit(token.charAt(i+2))) { + int altMajor = Character.digit(token.charAt(i), radix); + int altMinor = Character.digit(token.charAt(i+2), radix); + // Avoid possibly confusing situations by putting some + // constraints on the upgrades we do to the major and + // minor versions + if ((altMajor == major && altMinor > minor) || + altMajor == major + 1) { + major = altMajor; + minor = altMinor; + } + } + } + } + } + } + } + valid = true; + } + catch (Exception e) + { + e.printStackTrace(); + // FIXME: refactor desktop OpenGL dependencies and make this + // class work properly for OpenGL ES + System.err.println("ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: "+e); + major = 1; + minor = 0; + /* + throw (IllegalArgumentException) + new IllegalArgumentException( + "Illegally formatted version identifier: \"" + versionString + "\"") + .initCause(e); + */ + } + } + + public boolean isValid() { + return valid; + } + + public int compareTo(Object o) + { + Version vo = (Version)o; + if (major > vo.major) return 1; + else if (major < vo.major) return -1; + else if (minor > vo.minor) return 1; + else if (minor < vo.minor) return -1; + else if (sub > vo.sub) return 1; + else if (sub < vo.sub) return -1; + + return 0; // they are equal + } + + public int getMajor() { + return major; + } + + public int getMinor() { + return minor; + } + + } // end class Version + } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java index a96736c00..31dbd46ae 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java @@ -113,7 +113,7 @@ public abstract class EGLContext extends GLContextImpl { } if (created) { - setGLFunctionAvailability(false); + setGLFunctionAvailability(false, -1, -1, -1); return CONTEXT_CURRENT_NEW; } return CONTEXT_CURRENT; @@ -150,6 +150,10 @@ public abstract class EGLContext extends GLContextImpl { } } + protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { + return 0; // FIXME + } + protected void create() throws GLException { long eglDisplay = ((EGLDrawable)drawable).getDisplay(); EGLGraphicsConfiguration config = ((EGLDrawable)drawable).getGraphicsConfiguration(); @@ -215,14 +219,14 @@ public abstract class EGLContext extends GLContextImpl { throw new GLException("Error making context 0x" + Long.toHexString(eglContext) + " current: error code " + EGL.eglGetError()); } - setGLFunctionAvailability(true); + setGLFunctionAvailability(true, contextAttrs[1], 0, CTX_IS_ARB_CREATED|CTX_PROFILE_CORE|CTX_OPTION_ANY); } public boolean isCreated() { return (eglContext != 0); } - protected void updateGLProcAddressTable() { + protected void updateGLProcAddressTable(int major, int minor, int ctp) { if (DEBUG) { System.err.println(getThreadName() + ": !!! Initializing EGL extension address table"); } @@ -235,7 +239,7 @@ public abstract class EGLContext extends GLContextImpl { eglExtProcAddressTable = new EGLExtProcAddressTable(); } resetProcAddressTable(getEGLExtProcAddressTable()); - super.updateGLProcAddressTable(); + super.updateGLProcAddressTable(major, minor, ctp); } public synchronized String getPlatformExtensionsString() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java index de7fd2ba4..0adede4ea 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java @@ -47,7 +47,7 @@ public class EGLExternalContext extends EGLContext { public EGLExternalContext(AbstractGraphicsScreen screen) { super(null, null); GLContextShareSet.contextCreated(this); - setGLFunctionAvailability(false); + setGLFunctionAvailability(false, 0, 0, 0); getGLStateTracker().setEnabled(false); // external context usage can't track state in Java } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java index d3a634792..364c2b91b 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java @@ -90,6 +90,10 @@ public abstract class MacOSXCGLContext extends GLContextImpl protected abstract boolean create(); + protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { + return 0; // FIXME + } + /** * Creates and initializes an appropriate OpenGl nsContext. Should only be * called by {@link makeCurrentImpl()}. @@ -150,7 +154,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl if (!CGL.makeCurrentContext(nsContext)) { throw new GLException("Error making nsContext current"); } - setGLFunctionAvailability(true); + setGLFunctionAvailability(true, 0, 0, 0); GLContextShareSet.contextCreated(this); return true; } @@ -184,7 +188,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl } if (created) { - setGLFunctionAvailability(false); + setGLFunctionAvailability(false, -1, -1, -1); return CONTEXT_CURRENT_NEW; } return CONTEXT_CURRENT; @@ -251,7 +255,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl } } - protected void updateGLProcAddressTable() { + protected void updateGLProcAddressTable(int major, int minor, int ctp) { if (DEBUG) { System.err.println("!!! Initializing CGL extension address table"); } @@ -261,7 +265,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl cglExtProcAddressTable = new CGLExtProcAddressTable(); } resetProcAddressTable(getCGLExtProcAddressTable()); - super.updateGLProcAddressTable(); + super.updateGLProcAddressTable(major, minor, ctp); } public String getPlatformExtensionsString() diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java index dde77cde6..248bbb4d6 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java @@ -56,7 +56,7 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { this.cglContext = cglContext; this.nsContext = nsContext; GLContextShareSet.contextCreated(this); - setGLFunctionAvailability(false); + setGLFunctionAvailability(false, 0, 0, 0); getGLStateTracker().setEnabled(false); // external context usage can't track state in Java } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java index 446f457be..5844b8edd 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java @@ -73,7 +73,7 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { } if (created) { - setGLFunctionAvailability(false); + setGLFunctionAvailability(false, -1, -1, -1); // Initialize render-to-texture support if requested DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); @@ -152,7 +152,7 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { if (!impl.makeCurrent(nsContext)) { throw new GLException("Error making nsContext current"); } - setGLFunctionAvailability(true); + setGLFunctionAvailability(true, 0, 0, 0); return true; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java index 9010d4461..9189b41f3 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java @@ -87,7 +87,7 @@ public class MacOSXJava2DCGLContext extends MacOSXCGLContext implements Java2DGL } if (created) { - setGLFunctionAvailability(false); + setGLFunctionAvailability(false, -1, -1, -1); return CONTEXT_CURRENT_NEW; } return CONTEXT_CURRENT; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java index da8b70eb8..aae376a6c 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java @@ -56,7 +56,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { System.err.println(getThreadName() + ": !!! Created external OpenGL context " + toHexString(hglrc) + " for " + this); } GLContextShareSet.contextCreated(this); - setGLFunctionAvailability(false); + setGLFunctionAvailability(false, 0, 0, 0); cfg.updateCapabilitiesByWGL(this); getGLStateTracker().setEnabled(false); // external context usage can't track state in Java } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java index b3f4c498c..5b6d65f62 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java @@ -122,6 +122,10 @@ public class WindowsWGLContext extends GLContextImpl { protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; } + protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { + return 0; // FIXME + } + /** * Creates and initializes an appropriate OpenGL context. Should only be * called by {@link #makeCurrentImpl()}. @@ -157,7 +161,7 @@ public class WindowsWGLContext extends GLContextImpl { if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), temp_hglrc)) { throw new GLException("Error making temp context current: 0x" + Integer.toHexString(WGL.GetLastError())); } - setGLFunctionAvailability(true); + setGLFunctionAvailability(true, 0, 0, 0); if( !isFunctionAvailable("wglCreateContextAttribsARB") || !isExtensionAvailable("WGL_ARB_create_context") ) { @@ -243,7 +247,7 @@ public class WindowsWGLContext extends GLContextImpl { if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), hglrc)) { throw new GLException("Error making old context current: 0x" + Integer.toHexString(WGL.GetLastError())); } - updateGLProcAddressTable(); + updateGLProcAddressTable(0, 0, 0); if(DEBUG) { System.err.println("WindowsWGLContext.create done (old ctx < 3.0 - no 3.0) 0x"+Long.toHexString(hglrc)); } @@ -255,7 +259,7 @@ public class WindowsWGLContext extends GLContextImpl { if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), hglrc)) { throw new GLException("Error making new context current: 0x" + Integer.toHexString(WGL.GetLastError())); } - updateGLProcAddressTable(); + updateGLProcAddressTable(0, 0, 0); if(DEBUG) { System.err.println("WindowsWGLContext.create done (new ctx >= 3.0) 0x"+Long.toHexString(hglrc)); } @@ -304,7 +308,7 @@ public class WindowsWGLContext extends GLContextImpl { } if (created) { - setGLFunctionAvailability(false); + setGLFunctionAvailability(false, -1, -1, -1); WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); @@ -353,7 +357,7 @@ public class WindowsWGLContext extends GLContextImpl { } } - protected void updateGLProcAddressTable() { + protected void updateGLProcAddressTable(int major, int minor, int ctp) { if (DEBUG) { System.err.println(getThreadName() + ": !!! Initializing WGL extension address table for " + this); } @@ -369,7 +373,7 @@ public class WindowsWGLContext extends GLContextImpl { wglExtProcAddressTable = new WGLExtProcAddressTable(); } resetProcAddressTable(getWGLExtProcAddressTable()); - super.updateGLProcAddressTable(); + super.updateGLProcAddressTable(major, minor, ctp); } public String getPlatformExtensionsString() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java index 783e3278a..b8f25aad7 100755 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java @@ -55,7 +55,7 @@ public class X11ExternalGLXContext extends X11GLXContext { super(drawable, null); this.context = context; GLContextShareSet.contextCreated(this); - setGLFunctionAvailability(false); + setGLFunctionAvailability(false, 0, 0, 0); getGLStateTracker().setEnabled(false); // external context usage can't track state in Java } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java index 142da672a..1492bfe42 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java @@ -110,6 +110,70 @@ public abstract class X11GLXContext extends GLContextImpl { */ protected abstract void create(); + protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + long display = config.getScreen().getDevice().getHandle(); + GLXExt glXExt = getGLXExt(); + + boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; + boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ; + boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ; + + long _context=0; + + String verstr = getGLVersion(null, major, minor, ctp, "@creation"); + + int attribs[] = { + /* 0 */ GLX.GLX_CONTEXT_MAJOR_VERSION_ARB, major, + /* 2 */ GLX.GLX_CONTEXT_MINOR_VERSION_ARB, minor, + /* 4 */ GLX.GLX_RENDER_TYPE, GLX.GLX_RGBA_TYPE, + /* 6 */ GLX.GLX_CONTEXT_FLAGS_ARB, 0, + /* 8 */ 0, 0, + /* 10 */ 0 + }; + + if ( major > 3 || major == 3 && minor >= 2 ) { + // FIXME: Verify with a None drawable binding (default framebuffer) + attribs[8+0] = GLX.GLX_CONTEXT_PROFILE_MASK_ARB; + if( ctBwdCompat ) { + attribs[8+1] = GLX.GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + } else { + attribs[8+1] = GLX.GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + } + } + + if ( major >= 3 ) { + if( !ctBwdCompat && ctFwdCompat ) { + attribs[6+1] |= GLX.GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + } + if( ctDebug) { + attribs[6+1] |= GLX.GLX_CONTEXT_DEBUG_BIT_ARB; + } + } + + _context = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0); + if(0==_context) { + if(DEBUG) { + System.err.println("X11GLXContext.createContextARB couldn't create "+verstr+" _context"); + } + } else { + if (!GLX.glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawableRead.getNativeWindow().getSurfaceHandle(), + _context)) { + if(DEBUG) { + System.err.println("X11GLXContext.createContextARB couldn't make "+verstr+" context current"); + } + GLX.glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, _context); + _context = 0; + } else if(DEBUG) { + System.err.println("X11GLXContext.createContextARB "+verstr+" available "+toHexString(_context)); + } + } + return _context; + } + /** * Creates and initializes an appropriate OpenGL context. Should only be * called by {@link create()}. @@ -133,176 +197,105 @@ public abstract class X11GLXContext extends GLContextImpl { } GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities(); + GLProfile glp = glCaps.getGLProfile(); isVendorATI = ((X11GLXDrawableFactory)(drawable.getFactoryImpl())).isVendorATI(); if(config.getFBConfigID()<0) { // not able to use FBConfig - if(glCaps.getGLProfile().isGL3()) { + if(glp.isGL3()) { throw new GLException("Unable to create OpenGL >= 3.1 context"); } context = GLX.glXCreateContext(display, config.getXVisualInfo(), share, direct); if (context == 0) { - throw new GLException("Unable to create OpenGL context"); + throw new GLException("Unable to create context(0)"); } if (!GLX.glXMakeContextCurrent(display, drawable.getNativeWindow().getSurfaceHandle(), drawableRead.getNativeWindow().getSurfaceHandle(), context)) { - throw new GLException("Error making temp context (old2) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); + throw new GLException("Error making temp context(0) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); } - setGLFunctionAvailability(true); + setGLFunctionAvailability(true, 0, 0, 0); // use GL_VERSION if(DEBUG) { - System.err.println("X11GLXContext.createContext done (old2 ctx) "+toHexString(context)); + System.err.println("X11GLXContext.createContext(0) done "+toHexString(context)); + } + return; + } + + // To use GLX_ARB_create_context, we have to make a temp context current, + // so we are able to use GetProcAddress + long temp_context = GLX.glXCreateNewContext(display, config.getFBConfig(), GLX.GLX_RGBA_TYPE, share, direct); + if (temp_context == 0) { + throw new GLException("Unable to create temp OpenGL context(1)"); + } + if (!GLX.glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawableRead.getNativeWindow().getSurfaceHandle(), + temp_context)) { + throw new GLException("Error making temp context(1) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); + } + setGLFunctionAvailability(true, 0, 0, 0); // use GL_VERSION + + if( !isFunctionAvailable("glXCreateContextAttribsARB") || + !isExtensionAvailable("GLX_ARB_create_context") ) { + if(glp.isGL3()) { + GLX.glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, temp_context); + throw new GLException("Unable to create OpenGL >= 3.1 context (no GLX_ARB_create_context)"); } + // continue with temp context for GL < 3.0 + context = temp_context; + if(DEBUG) { + System.err.println("X11GLXContext.createContext(1) done (!GLX_ARB_create_context) "+toHexString(context)); + } + return; + } + + int minor[] = new int[1]; + int major[] = new int[1]; + int ctp[] = new int[1]; + context = createContextARB(share, direct, major, minor, ctp); + + if(0!=context) { + // need to update the GL func table .. + setGLFunctionAvailability(true, major[0], minor[0], ctp[0]); + + GLX.glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, temp_context); + if (!GLX.glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawableRead.getNativeWindow().getSurfaceHandle(), + context)) { + throw new GLException("Cannot make previous verified context current"); + } + if(DEBUG) { + System.err.println("X11GLXContext.createContext(2) done "+getGLVersion(null, major[0], minor[0], ctp[0], "@creation")+", "+toHexString(context)); + } } else { + if(DEBUG) { + System.err.println("X11GLXContext.createContext(2) failed "+getGLVersion(null, major[0], minor[0], ctp[0], "@creation")); + } + if(!glp.isGL2()) { + GLX.glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, temp_context); + throw new GLException("Unable to create context(2) (have GLX_ARB_create_context)"); + } - // To use GLX_ARB_create_context, we have to make a temp context current, - // so we are able to use GetProcAddress - long temp_context = GLX.glXCreateNewContext(display, config.getFBConfig(), GLX.GLX_RGBA_TYPE, share, direct); - if (temp_context == 0) { - throw new GLException("Unable to create temp OpenGL context"); - } else { - if (!GLX.glXMakeContextCurrent(display, - drawable.getNativeWindow().getSurfaceHandle(), - drawableRead.getNativeWindow().getSurfaceHandle(), - temp_context)) { - throw new GLException("Error making temp context (old) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); - } - setGLFunctionAvailability(true); - - if( !isFunctionAvailable("glXCreateContextAttribsARB") || - !isExtensionAvailable("GLX_ARB_create_context") ) { - if(glCaps.getGLProfile().isGL3()) { - GLX.glXMakeContextCurrent(display, 0, 0, 0); - GLX.glXDestroyContext(display, temp_context); - throw new GLException("Unable to create OpenGL >= 3.1 context (no GLX_ARB_create_context)"); - } - - // continue with temp context for GL < 3.0 - context = temp_context; - if(DEBUG) { - System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no GLX_ARB_create_context) "+toHexString(context)); - } - } else { - GLXExt glXExt = getGLXExt(); - - // preset with default values - int attribs[] = { - /* 0 */ GLX.GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - /* 2 */ GLX.GLX_CONTEXT_MINOR_VERSION_ARB, 0, - /* 4 */ GLX.GLX_RENDER_TYPE, GLX.GLX_RGBA_TYPE, - /* 6 */ GLX.GLX_CONTEXT_FLAGS_ARB, 0 /* GLX.GLX_CONTEXT_DEBUG_BIT_ARB */, - /* 8 */ 0, 0, - /* 10 */ 0 - }; - - if(glCaps.getGLProfile().isGL3()) { - // Try >= 3.2 core first - // and verify with a None drawable binding (default framebuffer) - attribs[0+1] = 3; - attribs[2+1] = 2; - if(glCaps.getGLProfile().isGL3bc()) { - attribs[8+0] = GLX.GLX_CONTEXT_PROFILE_MASK_ARB; - attribs[8+1] = GLX.GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - } - /** - * don't stricten requirements any further, even compatible would be fine - * - else { - attribs[8+0] = GLX.GLX_CONTEXT_PROFILE_MASK_ARB; - attribs[8+1] = GLX.GLX_CONTEXT_CORE_PROFILE_BIT_ARB; - } - */ - - context = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0); - if(0!=context) { - if (!GLX.glXMakeContextCurrent(display, - drawable.getNativeWindow().getSurfaceHandle(), - drawableRead.getNativeWindow().getSurfaceHandle(), - context)) { - if(DEBUG) { - System.err.println("X11GLXContext.createContext couldn't make >= 3.2 core context current - fallback"); - } - GLX.glXMakeContextCurrent(display, 0, 0, 0); - GLX.glXDestroyContext(display, context); - context = 0; - } else if(DEBUG) { - System.err.println("X11GLXContext.createContext >= 3.2 available "+toHexString(context)); - } - } else { - if(DEBUG) { - System.err.println("X11GLXContext.createContext couldn't create >= 3.2 core context - fallback"); - } - } - if(0==context) { - // Try >= 3.1 forward compatible - last resort for GL3 ! - attribs[0+1] = 3; - attribs[2+1] = 1; - if(!glCaps.getGLProfile().isGL3bc()) { - attribs[6+1] |= GLX.GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; - } - attribs[8+0] = 0; - attribs[8+1] = 0; - } - } - if(0==context) { - // 3.1 or 3.0 .. - context = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0); - if(0!=context) { - if (!GLX.glXMakeContextCurrent(display, - drawable.getNativeWindow().getSurfaceHandle(), - drawableRead.getNativeWindow().getSurfaceHandle(), - context)) { - if(DEBUG) { - System.err.println("X11GLXContext.createContext couldn't make >= 3.0 core context current - fallback"); - } - GLX.glXMakeContextCurrent(display, 0, 0, 0); - GLX.glXDestroyContext(display, context); - context = 0; - } else if(DEBUG) { - System.err.println("X11GLXContext.createContext >= 3.0 available "+toHexString(context)); - } - } else { - if(DEBUG) { - System.err.println("X11GLXContext.createContext couldn't create >= 3.0 core context - fallback"); - } - } - } - - if(0==context) { - if(glCaps.getGLProfile().isGL3()) { - GLX.glXMakeContextCurrent(display, 0, 0, 0); - GLX.glXDestroyContext(display, temp_context); - throw new GLException("Unable to create OpenGL >= 3.1 context (have GLX_ARB_create_context)"); - } - - // continue with temp context for GL < 3.0 - context = temp_context; - if (!GLX.glXMakeContextCurrent(display, - drawable.getNativeWindow().getSurfaceHandle(), - drawableRead.getNativeWindow().getSurfaceHandle(), - context)) { - GLX.glXMakeContextCurrent(display, 0, 0, 0); - GLX.glXDestroyContext(display, temp_context); - throw new GLException("Error making context (old) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); - } - if(DEBUG) { - System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no 3.0) "+toHexString(context)); - } - } else { - GLX.glXDestroyContext(display, temp_context); - - // need to update the GL func table .. - updateGLProcAddressTable(); - if(DEBUG) { - System.err.println("X11GLXContext.createContext done (new ctx >= 3.0) "+toHexString(context)); - } - } - } - } - } - GLContextShareSet.contextCreated(this); + // continue with temp context for GL <= 3.0 + context = temp_context; + if (!GLX.glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawableRead.getNativeWindow().getSurfaceHandle(), + context)) { + GLX.glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, temp_context); + throw new GLException("Error making context(1) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); + } + if(DEBUG) { + System.err.println("X11GLXContext.createContext(1) done "+toHexString(context)); + } + } } // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release] @@ -350,6 +343,7 @@ public abstract class X11GLXContext extends GLContextImpl { boolean created = false; if (context == 0) { create(); + GLContextShareSet.contextCreated(this); if (DEBUG) { System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName()); } @@ -374,7 +368,7 @@ public abstract class X11GLXContext extends GLContextImpl { } if (created) { - setGLFunctionAvailability(false); + setGLFunctionAvailability(false, -1, -1, -1); return CONTEXT_CURRENT_NEW; } return CONTEXT_CURRENT; @@ -441,7 +435,7 @@ public abstract class X11GLXContext extends GLContextImpl { } } - protected void updateGLProcAddressTable() { + protected void updateGLProcAddressTable(int major, int minor, int ctp) { if (DEBUG) { System.err.println(getThreadName() + ": !!! Initializing GLX extension address table"); } @@ -454,7 +448,7 @@ public abstract class X11GLXContext extends GLContextImpl { glXExtProcAddressTable = new GLXExtProcAddressTable(); } resetProcAddressTable(getGLXExtProcAddressTable()); - super.updateGLProcAddressTable(); + super.updateGLProcAddressTable(major, minor, ctp); } public synchronized String getPlatformExtensionsString() { diff --git a/src/jogl/classes/javax/media/opengl/GL4.java b/src/jogl/classes/javax/media/opengl/GL4.java new file mode 100644 index 000000000..29a316333 --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/GL4.java @@ -0,0 +1,5 @@ +package javax.media.opengl; + +public interface GL4 extends GLBase { +} + diff --git a/src/jogl/classes/javax/media/opengl/GL4bc.java b/src/jogl/classes/javax/media/opengl/GL4bc.java new file mode 100644 index 000000000..be1131e91 --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/GL4bc.java @@ -0,0 +1,5 @@ +package javax.media.opengl; + +public interface GL4bc extends GL4 { +} + diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java index 369907c22..5ba410a61 100644 --- a/src/jogl/classes/javax/media/opengl/GLBase.java +++ b/src/jogl/classes/javax/media/opengl/GLBase.java @@ -64,6 +64,20 @@ public interface GLBase { public boolean isGL(); /** + * Indicates whether this GL object conforms to the GL4 compatibility profile. + * The GL4 compatibility profile merges the GL2 profile and GL4 core profile. + * @return whether this GL object conforms to the GL4 compatibility profile + */ + public boolean isGL4bc(); + + /** + * Indicates whether this GL object conforms to the GL4 core profile. + * The GL4 core profile reflects OpenGL versions greater or equal 3.1 + * @return whether this GL object conforms to the GL4 core profile + */ + public boolean isGL4(); + + /** * Indicates whether this GL object conforms to the GL3 compatibility profile. * The GL3 compatibility profile merges the GL2 profile and GL3 core profile. * @return whether this GL object conforms to the GL3 compatibility profile @@ -131,6 +145,20 @@ public interface GLBase { public GL getGL() throws GLException; /** + * Casts this object to the GL4bc interface. + * @return this object cast to the GL4bc interface + * @throws GLException if this GLObject is not a GL4bc implementation + */ + public GL4bc getGL4bc() throws GLException; + + /** + * Casts this object to the GL4 interface. + * @return this object cast to the GL4 interface + * @throws GLException if this GLObject is not a GL4 implementation + */ + public GL4 getGL4() throws GLException; + + /** * Casts this object to the GL3bc interface. * @return this object cast to the GL3bc interface * @throws GLException if this GLObject is not a GL3bc implementation diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index 1e52c2a65..a8dbf9213 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -260,7 +260,9 @@ public abstract class GLContext { public final String toString() { StringBuffer sb = new StringBuffer(); sb.append(getClass().getName()); - sb.append(" ["); + sb.append(" [OpenGL "); + sb.append(getGLVersion()); + sb.append(", "); sb.append(getGL()); if(getGLDrawable()!=getGLDrawableRead()) { sb.append(",\n\tDrawable Read : "); @@ -280,4 +282,68 @@ public abstract class GLContext { GLX) extensions. Can only be called while this context is current. */ public abstract String getPlatformExtensionsString(); + + public final int getGLVersionMajor() { return ctxMajorVersion; } + public final int getGLVersionMinor() { return ctxMajorVersion; } + public final boolean isGLCompatibilityProfile() { return ( 0 != ( CTX_PROFILE_COMPAT & ctxOptions ) ); } + public final boolean isGLForwardCompatible() { return ( 0 != ( CTX_OPTION_FORWARD & ctxOptions ) ); } + + /** + * Returns a valid OpenGL version string, ie + * <code>major.minor ([option]?[options,]*) - gl-version</code> + * + * <ul> + * <li> options + * <ul> + * <li> <code>old</code> refers to the non ARB_create_context created context + * <li> <code>new</code> refers to the ARB_create_context created context + * <li> <code>compatible profile</code> + * <li> <code>core profile</code> + * <li> <code>forward compatible</code> + * <li> <code>any</code> refers to the non forward compatible context + * <li> <code>ES</code> refers to the GLES context variant + * </ul> + * <li> <i>gl-version</i> the GL_VERSION string + * </ul> + * + * e.g.: + * <table border="0"> + * <tr> <td></td> <td></td> </tr> + * <tr> + * <td>row 2, cell 1</td> + * <td>row 2, cell 2</td> + * </tr> + * </table> + * + * <table border="0"> + * <tr><td></td> <td>ES2</td> <td><code>2.0 (ES, any, new) - 2.0 ES Profile</code></td></tr> + * <tr><td>ATI</td><td>GL2</td> <td><code>3.0 (compatibility profile, any, new) - 3.2.9704 Compatibility Profile Context</code></td></tr> + * <tr><td>ATI</td><td>GL3</td> <td><code>3.3 (core profile, any, new) - 1.4 (3.2.9704 Compatibility Profile Context)</code></td></tr> + * <tr><td>ATI</td><td>GL3bc</td><td><code>3.3 (compatibility profile, any, new) - 1.4 (3.2.9704 Compatibility Profile Context)</code></td></tr> + * <tr><td>NV</td><td>GL2</td> <td><code>3.0 (compatibility profile, any, new) - 3.0.0 NVIDIA 195.36.07.03</code></td></tr> + * <tr><td>NV</td><td>GL3</td> <td><code>3.3 (core profile, any, new) - 3.3.0 NVIDIA 195.36.07.03</code></td></tr> + * <tr><td>NV</td><td>GL3bc</td> <td><code>3.3 (compatibility profile, any, new) - 3.3.0 NVIDIA 195.36.07.03</code></td></tr> + * </table> + */ + public final String getGLVersion() { + return ctxVersionString; + } + + protected int ctxMajorVersion=-1; + protected int ctxMinorVersion=-1; + protected int ctxOptions=0; + protected String ctxVersionString=null; + + /** <code>ARB_create_context</code> related: created via ARB_create_context */ + protected static final int CTX_IS_ARB_CREATED = 1 << 0; + /** <code>ARB_create_context</code> related: compatibility profile */ + protected static final int CTX_PROFILE_COMPAT = 1 << 1; + /** <code>ARB_create_context</code> related: core profile */ + protected static final int CTX_PROFILE_CORE = 1 << 2; + /** <code>ARB_create_context</code> related: flag forward compatible */ + protected static final int CTX_OPTION_FORWARD = 1 << 3; + /** <code>ARB_create_context</code> related: not flag forward compatible */ + protected static final int CTX_OPTION_ANY = 1 << 4; + /** <code>ARB_create_context</code> related: flag debug */ + protected static final int CTX_OPTION_DEBUG = 1 << 5; } diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 755fae73d..231faab8c 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -62,6 +62,13 @@ public class GLProfile implements Cloneable { // Public (user-visible) profiles // + /** The desktop OpenGL compatibility profile 4.x, with x >= 0, ie GL2 plus GL4.<br> + <code>bc</code> 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.<br> <code>bc</code> stands for backward compatibility. */ public static final String GL3bc = "GL3bc"; @@ -90,12 +97,12 @@ public class GLProfile implements Cloneable { /** * 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, GL3bc, 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, GL3bc, 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 @@ -193,7 +200,11 @@ public class GLProfile implements Cloneable { } private static final String getGLImplBaseClassName(String profileImpl) { - if(GL3bc.equals(profileImpl)) { + if(GL4bc.equals(profileImpl)) { + return "com.jogamp.opengl.impl.gl4.GL4bc"; + } else if(GL4.equals(profileImpl)) { + return "com.jogamp.opengl.impl.gl4.GL4"; + } else if(GL3bc.equals(profileImpl)) { return "com.jogamp.opengl.impl.gl3.GL3bc"; } else if(GL3.equals(profileImpl)) { return "com.jogamp.opengl.impl.gl3.GL3"; @@ -254,19 +265,29 @@ public class GLProfile implements Cloneable { return profileImpl; } + /** Indicates whether this profile is capable of GL4bc. */ + public final boolean isGL4bc() { + return GL4bc.equals(profile); + } + + /** Indicates whether this profile is capable of GL4. */ + public final boolean isGL4() { + return isGL4bc() || GL4.equals(profile); + } + /** Indicates whether this profile is capable of GL3bc. */ public final boolean isGL3bc() { - return GL3bc.equals(profile); + return isGL4bc() || GL3bc.equals(profile); } /** Indicates whether this profile is capable of GL3. */ public final boolean isGL3() { - return isGL3bc() || GL3.equals(profile); + return isGL4() || isGL3bc() || GL3.equals(profile); } /** Indicates whether this profile is capable of GL2. */ public final boolean isGL2() { - return GL2.equals(profile); + return isGL3bc() || GL2.equals(profile); } /** Indicates whether this profile is capable of GLES1. */ @@ -294,24 +315,14 @@ public class GLProfile implements Cloneable { return GL2GL3.equals(profile) || isGL2() || isGL3() ; } - /** Indicates whether this profile uses the native OpenGL ES1 implementations. */ - public final boolean usesNativeGLES1() { - return GLES1.equals(profileImpl); + /** Indicates whether this profile uses the native desktop OpenGL GL4bc implementations. */ + public final boolean usesNativeGL4bc() { + return GL4bc.equals(profileImpl); } - /** Indicates whether this profile uses the native OpenGL ES2 implementations. */ - public final boolean usesNativeGLES2() { - return GLES2.equals(profileImpl); - } - - /** Indicates whether this profile uses either of the native OpenGL ES implementations. */ - public final boolean usesNativeGLES() { - return usesNativeGLES2() || usesNativeGLES1(); - } - - /** Indicates whether this profile uses the native desktop OpenGL GL2 implementations. */ - public final boolean usesNativeGL2() { - return GL2.equals(profileImpl) || GL2ES12.equals(profileImpl) ; + /** Indicates whether this profile uses the native desktop OpenGL GL4 implementations. */ + public final boolean usesNativeGL4() { + return usesNativeGL4bc() || GL4.equals(profileImpl); } /** Indicates whether this profile uses the native desktop OpenGL GL3bc implementations. */ @@ -324,9 +335,29 @@ public class GLProfile implements Cloneable { return usesNativeGL3bc() || GL3.equals(profileImpl); } + /** Indicates whether this profile uses the native desktop OpenGL GL2 implementations. */ + public final boolean usesNativeGL2() { + return GL2.equals(profileImpl) || GL2ES12.equals(profileImpl) ; + } + /** Indicates whether this profile uses the native desktop OpenGL GL2 or GL3 implementations. */ public final boolean usesNativeGL2GL3() { - return usesNativeGL2() || usesNativeGL3() ; + return usesNativeGL2() || usesNativeGL3() || usesNativeGL4(); + } + + /** Indicates whether this profile uses the native OpenGL ES1 implementations. */ + public final boolean usesNativeGLES1() { + return GLES1.equals(profileImpl); + } + + /** Indicates whether this profile uses the native OpenGL ES2 implementations. */ + public final boolean usesNativeGLES2() { + return GLES2.equals(profileImpl); + } + + /** Indicates whether this profile uses either of the native OpenGL ES implementations. */ + public final boolean usesNativeGLES() { + return usesNativeGLES2() || usesNativeGLES1(); } /** Indicates whether this profile supports GLSL. */ @@ -634,6 +665,49 @@ public class GLProfile implements Cloneable { return "GLProfile[" + profile + "/" + profileImpl + "]"; } + public static final int GL_VERSIONS[][] = { + /* 0.*/ { -1 }, + /* 1.*/ { 0, 1, 2, 3, 4, 5 }, + /* 2.*/ { 0, 1 }, + /* 3.*/ { 0, 1, 2, 3 }, + /* 4.*/ { 0 } }; + + public static final int getMaxMajor() { + return GL_VERSIONS.length-1; + } + + public static final int getMaxMinor(int major) { + if(1>major || 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"; |