From 4c32ea23370336b99eba4c1ebd1f07c409219a15 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 29 May 2009 01:47:02 +0000 Subject: JOGL Added OpenGL 3.0 and 3.1 support 3.0 as part of GL2 (extensions only) 3.1 forward compatible as GL3, ie doesn't contain the GL2 fixed function stuff etc Added code to retrieve a 3.0/3.1 context: X11/GLX and Windows/WGL TODO: MacOSX !! Updated GL and GLX extensions Fixing auto GLProfile selection, determine if GL2ES[1] uses GL2 or ES Usage of the unified GraphicsConfiguration of NativeWindow for all platforms. Sure, the broken OS (Win32/MacOSX) have a update mechanism for theit queried Capabilities after drawable creation. Adding X11/GLX GLXFBConfig usage and fixing it's attribute mapping Fixing GLX/X11 FBConfig/XVisual query function's memory leak, using a manual implementation, which copies the data and calls XFree. Added WGL extension WGL_ARB_create_context Tested: Linux x86 and x86_64 GL2, ES2 and ES1 Note: Nvidia driver couldn't make the succesfully created 3.1 context current. TODO: Verify Windows and MacOSX !! git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1919 232f8b59-042b-4e1e-8c03-345bb8c30851 --- src/jogl/classes/javax/media/opengl/GLBase.java | 21 ++++- .../classes/javax/media/opengl/GLCapabilities.java | 22 ++--- src/jogl/classes/javax/media/opengl/GLContext.java | 2 +- .../javax/media/opengl/GLDrawableFactory.java | 16 ++-- src/jogl/classes/javax/media/opengl/GLProfile.java | 97 ++++++++++++++++------ .../classes/javax/media/opengl/awt/GLCanvas.java | 56 +++++++------ .../classes/javax/media/opengl/awt/GLJPanel.java | 4 +- 7 files changed, 142 insertions(+), 76 deletions(-) (limited to 'src/jogl/classes/javax') diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java index 9d88bae58..dcbd3e4cf 100644 --- a/src/jogl/classes/javax/media/opengl/GLBase.java +++ b/src/jogl/classes/javax/media/opengl/GLBase.java @@ -19,8 +19,16 @@ public interface GLBase { */ public boolean isGL(); + /** + * Indicates whether this GL object conforms to the GL3 profile. + * The GL3 profile reflects OpenGL versions greater or equal 3.1 + * @return whether this GL object conforms to the GL3 profile + */ + public boolean isGL3(); + /** * Indicates whether this GL object conforms to the GL2 profile. + * The GL2 profile reflects OpenGL versions greater or equal 1.5 * @return whether this GL object conforms to the GL2 profile */ public boolean isGL2(); @@ -38,19 +46,19 @@ public interface GLBase { public boolean isGLES2(); /** - * Indicates whether this GL object conforms to one of the OpenGL ES profiles. + * Indicates whether this GL object conforms to one of the OpenGL ES compatible profiles. * @return whether this GL object conforms to one of the OpenGL ES profiles */ public boolean isGLES(); /** - * Indicates whether this GL object conforms to the GL2ES1 profile. + * Indicates whether this GL object conforms to the GL2ES1 compatible profile. * @return whether this GL object conforms to the GL2ES1 profile */ public boolean isGL2ES1(); /** - * Indicates whether this GL object conforms to the GL2ES2 profile. + * Indicates whether this GL object conforms to the GL2ES2 compatible profile. * @return whether this GL object conforms to the GL2ES2 profile */ public boolean isGL2ES2(); @@ -62,6 +70,13 @@ public interface GLBase { */ public GL getGL() throws GLException; + /** + * Casts this object to the GL3 interface. + * @return this object cast to the GL3 interface + * @throws GLException if this GLObject is not a GL3 implementation + */ + public GL3 getGL3() throws GLException; + /** * Casts this object to the GL2 interface. * @return this object cast to the GL2 interface diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java index 35b04d5f6..0a73856c0 100644 --- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java +++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java @@ -288,23 +288,23 @@ public class GLCapabilities extends Capabilities implements Cloneable { /** Returns a textual representation of this GLCapabilities object. */ public String toString() { - return ("GLCapabilities [" + - "DoubleBuffered: " + doubleBuffered + + return getClass().toString()+"[" + + super.toString()+ + ", DoubleBuffered: " + doubleBuffered + ", Stereo: " + stereo + - ", HardwareAccelerated: " + hardwareAccelerated + + ", HardwareAccelerated: " + hardwareAccelerated + ", DepthBits: " + depthBits + ", StencilBits: " + stencilBits + - ", Red: " + getRedBits() + - ", Green: " + getGreenBits() + - ", Blue: " + getBlueBits() + - ", Alpha: " + getAlphaBits() + ", Red Accum: " + accumRedBits + ", Green Accum: " + accumGreenBits + ", Blue Accum: " + accumBlueBits + ", Alpha Accum: " + accumAlphaBits + - ", Multisample: " + sampleBuffers + - (sampleBuffers ? ", Num samples: " + numSamples : "") + - ", Opaque: " + backgroundOpaque + - " ]"); + ", Multisample: " + sampleBuffers + + ", Num samples: "+(sampleBuffers ? numSamples : 0) + + ", Opaque: " + backgroundOpaque + + ", PBuffer-FloatingPointBuffers: "+pbufferFloatingPointBuffers+ + ", PBuffer-RenderToTexture: "+pbufferRenderToTexture+ + ", PBuffer-RenderToTextureRectangle: "+pbufferRenderToTextureRectangle+ + " ]"; } } diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index 8c3ca9c5b..c7e5899a7 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -56,7 +56,7 @@ import java.util.HashMap; refer to a given context. */ public abstract class GLContext { - protected static final boolean DEBUG = Debug.debug("GLContext"); + protected static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.GLContext"); // Debug.debug("GLContext"); /** Indicates that the context was not made current during the last call to {@link #makeCurrent makeCurrent}. */ public static final int CONTEXT_NOT_CURRENT = 0; diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index 7e46b822c..e9208f49e 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -93,18 +93,18 @@ public abstract class GLDrawableFactory { public static GLDrawableFactory getFactory() throws GLException { if (null == factory) { if (null == GLProfile.getProfile()) { - throw new GLException("GLProfile was not properly initialized"); + GLProfile.setProfileGLAny(); // do it now .. last resort } // See if the user is requesting one of the embedded profiles, // and if so, try to instantiate the EGLDrawableFactory - if (GLProfile.isGLES()) { + if ( GLProfile.usesNativeGLES() ) { try { factory = (GLDrawableFactory) NWReflection.createInstance("com.sun.opengl.impl.egl.EGLDrawableFactory"); } catch (Exception e) { e.printStackTrace(); } - } else if (!GLProfile.isGL2ES1() && !GLProfile.isGL2ES2()) { + } else if ( !GLProfile.isGL2ES1() && !GLProfile.isGL2ES2() ) { // We require that the user passes in one of the known profiles throw new GLException("Unknown or unsupported profile \"" + GLProfile.getProfile() + "\""); } @@ -154,7 +154,9 @@ public abstract class GLDrawableFactory { /** * Returns a GLDrawable that wraps a platform-specific window system - * object, such as an AWT or LCDUI Canvas. On platforms which + * object, such as an AWT or LCDUI Canvas. + * On platforms which support pixel format, the NativeWindow's AbstractGraphicsConfiguration + * is being used. * support it, selects a pixel format compatible with the supplied * GLCapabilities, or if the passed GLCapabilities object is null, * uses a default set of capabilities. On these platforms, uses @@ -165,10 +167,10 @@ public abstract class GLDrawableFactory { * @throws IllegalArgumentException if the passed target is null * @throws GLException if any window system-specific errors caused * the creation of the GLDrawable to fail. + * + * @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen) */ - public abstract GLDrawable createGLDrawable(NativeWindow target, - GLCapabilities capabilities, - GLCapabilitiesChooser chooser) + public abstract GLDrawable createGLDrawable(NativeWindow target) throws IllegalArgumentException, GLException; //---------------------------------------------------------------------- diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 8c5d8a3bf..bf0f5bbb5 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -43,10 +43,15 @@ import com.sun.opengl.impl.*; import com.sun.nativewindow.impl.NWReflection; public class GLProfile { + public static final boolean DEBUG = Debug.debug("GLProfile"); + // // Public (user-visible) profiles // + /** The desktop (OpenGL 3.1) profile */ + public static final String GL3 = "GL3"; + /** The desktop (OpenGL 2.0) profile */ public static final String GL2 = "GL2"; @@ -79,28 +84,30 @@ public class GLProfile { private static final Throwable tryLibrary() { + String clazzName = getGLImplBaseClassName() + "Impl" ; try { - Class clazz = Class.forName(getGLImplBaseClassName()+"Impl"); - if(GL2.equals(realProfile)) { + Class clazz = Class.forName(clazzName); + if(GL3.equals(realProfile) || GL2.equals(realProfile)) { // See DRIHack.java for an explanation of why this is necessary DRIHack.begin(); - NativeLibLoader.loadGL2(); + NativeLibLoader.loadGLDesktop(); DRIHack.end(); } if(GL2ES12.equals(realProfile)) { // See DRIHack.java for an explanation of why this is necessary DRIHack.begin(); NativeLibLoader.loadGL2ES12(); DRIHack.end(); - } else if(GLES1.equals(realProfile) || GLES2.equals(realProfile)) { + } else if(usesNativeGLES()) { Object eGLDrawableFactory = NWReflection.createInstance("com.sun.opengl.impl.egl.EGLDrawableFactory"); if(null==eGLDrawableFactory) { throw new GLException("com.sun.opengl.impl.egl.EGLDrawableFactory not available"); } } - System.out.println("Successfully loaded profile " + profile); + System.out.println("Successfully loaded profile " + profile + " ("+realProfile+"/"+clazzName+")"); return null; } catch (Throwable e) { - if (Debug.debug("GLProfile")) { + if (DEBUG) { + System.err.println("GLProfile.tryLibrary: failed: " + profile + " ("+realProfile+"/"+clazzName+")"); e.printStackTrace(); } profile=null; @@ -109,13 +116,26 @@ public class GLProfile { } } - private static void computeRealProfile() { + private static boolean hasGL2ES12Impl = null!=NWReflection.getClass("com.sun.opengl.impl.gl2es12.GL2ES12Impl"); + private static boolean hasGL2Impl = null!=NWReflection.getClass("com.sun.opengl.impl.gl2.GL2Impl"); + + private static String computeRealProfile() { if (GL2ES1.equals(profile) || GL2ES2.equals(profile)) { - realProfile = GL2ES12; - } else { - realProfile = profile; + if(hasGL2Impl) { + realProfile = GL2; + return realProfile; + } else if(hasGL2ES12Impl) { + realProfile = GL2ES12; + return realProfile; + } } + realProfile = profile; + return realProfile; + } + + private static final void initStatics() { + GLDrawableFactory.getFactory(); } public static synchronized final void setProfile(String profile) @@ -123,11 +143,12 @@ public class GLProfile { { if(null==GLProfile.profile) { GLProfile.profile = profile; - computeRealProfile(); + String rp = computeRealProfile(); Throwable t = tryLibrary(); if (GLProfile.profile == null) { - throw new GLException("Profile " + profile + " not available", t); + throw new GLException("Profile " + profile + " ("+rp+") not available", t); } + initStatics(); } else { if(!GLProfile.profile.equals(profile)) { throw new GLException("Requested profile ("+profile+") doesn't match already chosen one: "+GLProfile.profile); @@ -159,6 +180,7 @@ public class GLProfile { msg.append("]"); throw new GLException("Profiles "+msg.toString()+" not available", t); } + initStatics(); } /** @@ -171,24 +193,28 @@ public class GLProfile { /** * Selects a profile, implementing the interface GL2ES2. - * Order: GL2ES2, GL2, GLES2 + * Order: GL2ES2, GL2, GL3, GLES2 */ public static synchronized final void setProfileGL2ES2() { - setProfile(new String[] { GL2ES2, GL2, GLES2 }); + setProfile(new String[] { GL2ES2, GL2, /*GL3,*/ GLES2 }); } /** * Selects a profile, implementing the interface GL - * Order: GL2, GL2ES2, GL2ES1, GLES2, GLES1 + * Order: GL2, GL2ES2, GL2ES1, GL3, GLES2, GLES1 */ public static synchronized final void setProfileGLAny() { - setProfile(new String[] { GL2, GL2ES2, GL2ES1, GLES2, GLES1 }); + setProfile(new String[] { GL2, GL2ES2, GL2ES1, /*GL3,*/ GLES2, GLES1 }); } public static final String getProfile() { return profile; } + public static final boolean isGL3() { + return GL3.equals(profile); + } + public static final boolean isGL2() { return GL2.equals(profile); } @@ -208,17 +234,31 @@ public class GLProfile { /* Indicates whether a GL2ES2 capable profile is in use, ie GL2ES2, GL2, GLES2 */ public static final boolean isGL2ES2() { - return GL2ES2.equals(profile) || isGL2() || isGLES2() ; + return GL2ES2.equals(profile) || isGL2() || isGL3() || isGLES2() ; } - /** Indicates whether either of the OpenGL ES profiles are in use. */ - public static final boolean isGLES() { - return isGLES2() || isGLES1(); + /** Indicates whether the native OpenGL ES1 profile is in use. + * This requires an EGL interface. + */ + public static final boolean usesNativeGLES1() { + return GLES1.equals(realProfile) || GL2ES1.equals(realProfile) ; + } + + /** Indicates whether the native OpenGL ES2 profile is in use. + * This requires an EGL interface. + */ + public static final boolean usesNativeGLES2() { + return GLES2.equals(realProfile) || GL2ES2.equals(realProfile) ; + } + + /** Indicates whether either of the native OpenGL ES profiles are in use. */ + public static final boolean usesNativeGLES() { + return usesNativeGLES2() || usesNativeGLES1(); } /** Indicates whether a GLSL capable profiles is in use. */ public static final boolean hasGLSL() { - return isGL2ES2(); + return isGL2ES2() ; } public static final boolean matches(String test_profile) { @@ -226,13 +266,15 @@ public class GLProfile { } public static final String getGLImplBaseClassName() { - if(isGL2()) { + if(GL3.equals(realProfile)) { + return "com.sun.opengl.impl.gl3.GL3"; + } else if(GL2.equals(realProfile)) { return "com.sun.opengl.impl.gl2.GL2"; - } else if(isGL2ES1() || isGL2ES2()) { + } else if(GL2ES12.equals(realProfile)) { return "com.sun.opengl.impl.gl2es12.GL2ES12"; - } else if(isGLES1()) { + } else if(GLES1.equals(realProfile) || GL2ES1.equals(realProfile)) { return "com.sun.opengl.impl.es1.GLES1"; - } else if(isGLES2()) { + } else if(GLES2.equals(realProfile) || GL2ES2.equals(realProfile)) { return "com.sun.opengl.impl.es2.GLES2"; } else { throw new GLException("unsupported profile \"" + profile + "\""); @@ -302,6 +344,9 @@ public class GLProfile { return true; } case javax.media.opengl.GL2.GL_DOUBLE: + if( isGL3() ) { + return true; + } case javax.media.opengl.GL2.GL_2_BYTES: case javax.media.opengl.GL2.GL_3_BYTES: case javax.media.opengl.GL2.GL_4_BYTES: @@ -431,7 +476,7 @@ public class GLProfile { } return false; } - } else if(GLProfile.isGL2ES2() || GLProfile.isGL2()) { + } else if( GLProfile.isGL2ES2() ) { if(isVertexAttribPointer) { switch(type) { case GL.GL_UNSIGNED_BYTE: diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 232299594..727d06b61 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -41,8 +41,7 @@ package javax.media.opengl.awt; import javax.media.opengl.*; import javax.media.nativewindow.*; -import javax.media.nativewindow.awt.AWTGraphicsDevice; -import javax.media.nativewindow.awt.AWTGraphicsConfiguration; +import javax.media.nativewindow.awt.*; import com.sun.opengl.impl.*; @@ -127,15 +126,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { GLCapabilitiesChooser chooser, GLContext shareWith, GraphicsDevice device) { - // The platform-specific GLDrawableFactory will only provide a - // non-null GraphicsConfiguration on platforms where this is - // necessary (currently only X11, as Windows allows the pixel - // format of the window to be set later and Mac OS X seems to - // handle this very differently than all other platforms). On - // other platforms this method returns null; it is the case (at - // least in the Sun AWT implementation) that this will result in - // equivalent behavior to calling the no-arg super() constructor - // for Canvas. /* * Workaround for Xinerama, always pass null so we can detect whether * super.getGraphicsConfiguration() is returning the Canvas' GC (null), @@ -146,22 +136,34 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { /* * Save the chosen capabilities for use in getGraphicsConfiguration(). */ - chosen = chooseGraphicsConfiguration(capabilities, chooser, device); - if (chosen != null) { + AWTGraphicsConfiguration config = chooseGraphicsConfiguration(capabilities, chooser, device); + if(DEBUG) { + Exception e = new Exception("Created Config: "+config); + e.printStackTrace(); + } + if(null!=config) { + // update .. + chosen = config.getGraphicsConfiguration(); + /* * If we are running on a platform that * must select a GraphicsConfiguration now, * save these for later use in getGraphicsConfiguration(). */ this.glCapChooser = chooser; - this.glCaps = capabilities; + this.glCaps = (GLCapabilities)config.getCapabilities(); } if (!Beans.isDesignTime()) { - drawable = GLDrawableFactory.getFactory().createGLDrawable(NativeWindowFactory.getFactory(getClass()).getNativeWindow(this), - capabilities, chooser); + if(null==config) { + throw new GLException("Error: AWTGraphicsConfiguration is null"); + } + drawable = GLDrawableFactory.getFactory().createGLDrawable(NativeWindowFactory.getNativeWindow(this, config)); context = (GLContextImpl) drawable.createContext(shareWith); context.setSynchronized(true); } + if(DEBUG) { + System.err.println("Created Drawable: "+drawable); + } } protected interface DestroyMethod { @@ -243,7 +245,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { * block, both devices should have the same visual list, and the * same configuration should be selected here. */ - final GraphicsConfiguration compatible = chooseGraphicsConfiguration(glCaps, glCapChooser, gc.getDevice()); + AWTGraphicsConfiguration config = chooseGraphicsConfiguration(glCaps, glCapChooser, gc.getDevice()); + final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null; if (compatible != null) { /* @@ -352,6 +355,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { super.addNotify(); if (!Beans.isDesignTime()) { disableBackgroundErase(); + drawable.setRealized(true); } } @@ -609,23 +613,23 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } } - private static GraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, - GLCapabilitiesChooser chooser, - GraphicsDevice device) { + private static AWTGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GraphicsDevice device) { // Make GLCanvas behave better in NetBeans GUI builder if (Beans.isDesignTime()) { return null; } - AWTGraphicsDevice awtDevice = new AWTGraphicsDevice(device); + AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device); AWTGraphicsConfiguration config = (AWTGraphicsConfiguration) - GraphicsConfigurationFactory.getFactory(awtDevice).chooseGraphicsConfiguration(capabilities, - chooser, - awtDevice); + GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capabilities, + chooser, + aScreen); if (config == null) { - return null; + throw new GLException("Error: Couldn't fetch AWTGraphicsConfiguration"); } - return config.getGraphicsConfiguration(); + return config; } } diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 86668373d..bf4176a08 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -41,6 +41,7 @@ package javax.media.opengl.awt; import javax.media.opengl.*; import javax.media.nativewindow.*; +import javax.media.nativewindow.awt.*; import java.awt.*; import java.awt.geom.*; @@ -142,8 +143,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { if (Java2D.isOGLPipelineActive() && Java2D.isFBOEnabled()) { Java2D.getShareContext(GraphicsEnvironment. getLocalGraphicsEnvironment(). - getDefaultScreenDevice(). - getDefaultConfiguration()); + getDefaultScreenDevice()); } GLProfile.setProfile(GLProfile.GL2); factory = GLDrawableFactoryImpl.getFactoryImpl(); -- cgit v1.2.3