diff options
author | Chien Yang <[email protected]> | 2004-10-01 01:04:36 +0000 |
---|---|---|
committer | Chien Yang <[email protected]> | 2004-10-01 01:04:36 +0000 |
commit | eced19d79a943c18f54dc7cbe693243e5953e792 (patch) | |
tree | 0d98627cc82661e26d4b94a1fce24c46f27261b9 /src | |
parent | 7a5f73109c44b123dd6e785163f2a2aa2d53730a (diff) |
With this fix Java 3D will require GLX 1.3 or higher to
compile or run.
1) Fixed issue 20 - Off-screen rendering doesn't work on Linux.
2) Cleanup native chooseOglVisual code.
git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@50 ba19aa83-45c5-6ac9-afd3-db810772062c
Diffstat (limited to 'src')
-rw-r--r-- | src/classes/linux/javax/media/j3d/J3dGraphicsConfig.java | 8 | ||||
-rw-r--r-- | src/classes/linux/javax/media/j3d/NativeConfigTemplate3D.java | 58 | ||||
-rw-r--r-- | src/classes/linux/javax/media/j3d/NativeScreenInfo.java | 19 | ||||
-rw-r--r-- | src/classes/share/javax/media/j3d/Canvas3D.java | 53 | ||||
-rw-r--r-- | src/classes/share/javax/media/j3d/ExceptionStrings.properties | 1 | ||||
-rw-r--r-- | src/classes/share/javax/media/j3d/GraphicsContext3D.java | 6 | ||||
-rw-r--r-- | src/classes/share/javax/media/j3d/Renderer.java | 16 | ||||
-rw-r--r-- | src/classes/solaris/javax/media/j3d/J3dGraphicsConfig.java | 12 | ||||
-rw-r--r-- | src/classes/solaris/javax/media/j3d/NativeConfigTemplate3D.java | 66 | ||||
-rw-r--r-- | src/classes/solaris/javax/media/j3d/NativeScreenInfo.java | 18 | ||||
-rw-r--r-- | src/native/d3d/Canvas3D.cpp | 9 | ||||
-rw-r--r-- | src/native/ogl/Canvas3D.c | 487 | ||||
-rw-r--r-- | src/native/ogl/NativeConfigTemplate3D.c | 482 | ||||
-rw-r--r-- | src/native/ogl/NativeScreenInfo.c | 69 |
14 files changed, 727 insertions, 577 deletions
diff --git a/src/classes/linux/javax/media/j3d/J3dGraphicsConfig.java b/src/classes/linux/javax/media/j3d/J3dGraphicsConfig.java index 9a4bb27..edf86c7 100644 --- a/src/classes/linux/javax/media/j3d/J3dGraphicsConfig.java +++ b/src/classes/linux/javax/media/j3d/J3dGraphicsConfig.java @@ -36,8 +36,10 @@ class J3dGraphicsConfig { } static boolean isValidConfig(GraphicsConfiguration gc) { - // Check to see if a valid visInfo pointer has been cached. - Object visInfoObject = Canvas3D.visInfoTable.get(gc); - return (visInfoObject != null) && (visInfoObject instanceof Long); + // Check to see if a valid FBConfig pointer has been cached. + Object fbConfigObject = Canvas3D.fbConfigTable.get(gc); + return ((fbConfigObject != null) && + (fbConfigObject instanceof Long)); + } } diff --git a/src/classes/linux/javax/media/j3d/NativeConfigTemplate3D.java b/src/classes/linux/javax/media/j3d/NativeConfigTemplate3D.java index e5b18f7..1a7869b 100644 --- a/src/classes/linux/javax/media/j3d/NativeConfigTemplate3D.java +++ b/src/classes/linux/javax/media/j3d/NativeConfigTemplate3D.java @@ -47,14 +47,14 @@ class NativeConfigTemplate3D { final static int NUM_ITEMS = 9; // Native method to get an OpenGL visual id and a pointer to the - // XVisualInfo struct itself. + // GLXFBConfig structure list itself. native int chooseOglVisual(long display, int screen, - int[] attrList, long[] visInfo); + int[] attrList, long[] fbConfig); - // Native method to free an XVisualInfo struct. This is static since it - // may need to be called to clean up the Canvas3D visInfoTable after the + // Native method to free an GLXFBConfig struct. This is static since it + // may need to be called to clean up the Canvas3D fbConfigTable after the // NativeConfigTemplate3D has been disposed of. - static native void freeVisual(long visInfo); + static native void freeFbConfig(long fbConfig); // Native methods to return whether a particular attribute is available native boolean isStereoAvailable(long display, int screen, int vid); @@ -64,7 +64,7 @@ class NativeConfigTemplate3D { /* - * Chooses the best visual for Java 3D apps. + * Chooses the best FBConfig for Java 3D apps. */ GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate3D template, @@ -73,8 +73,12 @@ class NativeConfigTemplate3D { X11GraphicsDevice gd = (X11GraphicsDevice)((X11GraphicsConfig)gc[0]).getDevice(); - NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd); + if (!NativeScreenInfo.isGLX13()) { + return null; + } + NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd); + long display = nativeScreenInfo.getDisplay(); int screen = nativeScreenInfo.getScreen(); @@ -92,7 +96,7 @@ class NativeConfigTemplate3D { if ((bounds.x != 0 || bounds.y != 0) && (! VirtualUniverse.mc.xineramaDisabled)) { // Xinerama is being used. The screen needs to be set to 0 since - // glxChooseVisual will not return a valid visual otherwise. + // glxChooseFBConfig will not return a valid visual otherwise. screen = 0; if (debug) { System.out.println(" Non-primary Xinerama screen:"); @@ -102,7 +106,7 @@ class NativeConfigTemplate3D { } int[] attrList; // holds the list of attributes to be translated - // for glxChooseVisual call + // for glxChooseFBConfig call attrList = new int[NUM_ITEMS]; @@ -116,15 +120,15 @@ class NativeConfigTemplate3D { attrList[STEREO] = template.getStereo(); attrList[ANTIALIASING] = template.getSceneAntialiasing(); - long[] visInfo = new long[1]; - int visID = chooseOglVisual(display, screen, attrList, visInfo); + long[] fbConfig = new long[1]; + int visID = chooseOglVisual(display, screen, attrList, fbConfig); if (debug) { System.out.println(" chooseOglVisual() returns " + visID); - System.out.println(" pointer to XVisualInfo is " + visInfo[0]); + System.out.println(" pointer to GLXFBConfig is " + fbConfig[0]); System.out.println(); } - if (visID == 0 || visInfo[0] == 0) { + if (visID == 0 || fbConfig[0] == 0) { return null; // no valid visual was found } @@ -139,14 +143,14 @@ class NativeConfigTemplate3D { // TODO: This may or may not be needed for Linux // To support disabling Solaris OpenGL Xinerama mode, we need to cache - // the pointer to the actual XVisualInfo that glXChooseVisual() + // the pointer to the actual GLXFBConfig that glXChooseFBConfig() // returns, since this is not cached with X11GraphicsConfig and there - // are no public constructors to allow us to extend it. - synchronized (Canvas3D.visInfoTable) { - if (Canvas3D.visInfoTable.get(gc1) == null) - Canvas3D.visInfoTable.put(gc1, new Long(visInfo[0])); + // are no public constructors to allow us to extend it. + synchronized (Canvas3D.fbConfigTable) { + if (Canvas3D.fbConfigTable.get(gc1) == null) + Canvas3D.fbConfigTable.put(gc1, new Long(fbConfig[0])); else - freeVisual(visInfo[0]); + freeFbConfig(fbConfig[0]); } return gc1; @@ -162,6 +166,10 @@ class NativeConfigTemplate3D { X11GraphicsDevice gd = (X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice(); + if (!NativeScreenInfo.isGLX13()) { + return false; + } + NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd); long display = nativeScreenInfo.getDisplay(); @@ -182,13 +190,13 @@ class NativeConfigTemplate3D { attrList[STEREO] = template.getStereo(); attrList[ANTIALIASING] = template.getSceneAntialiasing(); - long[] visInfo = new long[1]; - int visID = chooseOglVisual(display, screen, attrList, visInfo); + long[] fbConfig = new long[1]; + int visID = chooseOglVisual(display, screen, attrList, fbConfig); - if (visID == 0 || visInfo[0] == 0) - return false; // no valid visual was found + if (visID == 0 || fbConfig[0] == 0) + return false; // no valid visual was found else - return true; + return true; } @@ -232,7 +240,7 @@ class NativeConfigTemplate3D { } - // Return whether scene antialiasing is available. + // Return whether scene antialiasing is available. boolean hasSceneAntialiasingMultiSamples(GraphicsConfiguration gc) { X11GraphicsDevice gd = (X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice(); diff --git a/src/classes/linux/javax/media/j3d/NativeScreenInfo.java b/src/classes/linux/javax/media/j3d/NativeScreenInfo.java index 2579f1f..aac8fa6 100644 --- a/src/classes/linux/javax/media/j3d/NativeScreenInfo.java +++ b/src/classes/linux/javax/media/j3d/NativeScreenInfo.java @@ -24,9 +24,28 @@ import sun.awt.X11GraphicsDevice; class NativeScreenInfo { private int screen; private static long display = 0; + private static boolean glxChecked = false; + private static boolean isGLX13; private native static long openDisplay(); private native static int getDefaultScreen(long display); + private native static boolean queryGLX13(long display); + + // Fix for issue 20. + // This method will return true if glx version is 1.3 or higher, + // else return false. + synchronized static boolean isGLX13() { + if (!glxChecked) { + // Open a new static display connection if one is not already opened. + getStaticDisplay(); + // Query for glx1.3 support. + isGLX13 = queryGLX13(display); + glxChecked = true; + } + + return isGLX13; + } + synchronized static long getStaticDisplay() { if (display == 0) { diff --git a/src/classes/share/javax/media/j3d/Canvas3D.java b/src/classes/share/javax/media/j3d/Canvas3D.java index fc693a6..eb979e6 100644 --- a/src/classes/share/javax/media/j3d/Canvas3D.java +++ b/src/classes/share/javax/media/j3d/Canvas3D.java @@ -1,3 +1,4 @@ + /* * $RCSfile$ * @@ -558,19 +559,20 @@ public class Canvas3D extends Canvas { // the visual id. int vid = 0; - // The visInfo field is only used when running X11. It contains a pointer - // to the native XVisualInfo structure, since in some cases the visual id + // Fix for issue 20. + // The fbConfig is only used when running X11. It contains a pointer + // to the native GLXFBConfig structure list, since in some cases the visual id // alone isn't sufficient for the native OpenGL renderer (e.g., when using // Solaris OpenGL with Xinerama mode disabled). - long visInfo = 0; + long fbConfig = 0; - // visInfoTable is a static hashtable which allows getBestConfiguration() + // fbConfigTable is a static hashtable which allows getBestConfiguration() // in NativeConfigTemplate3D to map a GraphicsConfiguration to the pointer - // to the actual XVisualInfo that glXChooseVisual() returns. The Canvas3D + // to the actual GLXFBConfig that glXChooseFBConfig() returns. The Canvas3D // doesn't exist at the time getBestConfiguration() is called, and // X11GraphicsConfig neither maintains this pointer nor provides a public // constructor to allow Java 3D to extend it. - static Hashtable visInfoTable = new Hashtable(); + static Hashtable fbConfigTable = new Hashtable(); // The native graphics version and renderer information String nativeGraphicsVersion = null; @@ -741,7 +743,7 @@ public class Canvas3D extends Canvas { static final int STENCIL_BUFFER = 0x1000; // The following three variables are set by - // createContext()/createQueryContext() callback + // createNewContext()/createQueryContext() callback // Supported Extensions int extensionsSupported = 0; @@ -800,16 +802,19 @@ public class Canvas3D extends Canvas { /* native int getTextureColorTableSize(long ctx); */ // This is the native method for creating the underlying graphics context. - native long createContext(long display, int window, int vid, long visInfo, - long shareCtx, boolean isSharedCtx, - boolean offScreen); + native long createNewContext(long display, int window, int vid, long fbConfig, + long shareCtx, boolean isSharedCtx, + boolean offScreen); + + native void createQueryContext(long display, int window, int vid, long fbConfig, + boolean offScreen, int width, int height); - native void createQueryContext(long display, int window, int vid, boolean offScreen, int width, int height); native static void destroyContext(long display, int window, long context); // This is the native for creating offscreen buffer - native int createOffScreenBuffer(long ctx, long display, int vid, int width, int height); - native void destroyOffScreenBuffer(long ctx, long display, int window); + native int createOffScreenBuffer(long ctx, long display, int window, long fbConfig, int width, int height); + + native void destroyOffScreenBuffer(long ctx, long display, long fbConfig, int window); // This is the native for reading the image from the offscreen buffer native void readOffScreenBuffer(long ctx, int format, int width, int height); @@ -1112,13 +1117,25 @@ public class Canvas3D extends Canvas { this.offScreen = offScreen; this.graphicsConfiguration = graphicsConfiguration; - Object visInfoObject; + // Needed for Win32 only. vid = nativeWSobj.getCanvasVid(graphicsConfiguration); - visInfoObject = visInfoTable.get(graphicsConfiguration); - if ((visInfoObject != null) && (visInfoObject instanceof Long)) { - visInfo = ((Long)visInfoObject).longValue(); + // Fix for issue 20. + // Needed for Linux and Solaris. + Object fbConfigObject; + fbConfigObject = fbConfigTable.get(graphicsConfiguration); + if ((fbConfigObject != null) && + (fbConfigObject instanceof Long)) { + fbConfig = ((Long)fbConfigObject).longValue(); + // System.out.println("Canvas3D creation FBConfig = " + fbConfig); + + if (fbConfig == 0) { + throw new IllegalArgumentException + (J3dI18N.getString("Canvas3D23")); + } } + + if (offScreen) { screen = new Screen3D(graphicsConfiguration, offScreen); @@ -3371,7 +3388,7 @@ public class Canvas3D extends Canvas { // inside the native code after setting the various // fields in this object createQueryContext(screen.display, window, vid, - offScreen, 10, 10); + fbConfig, offScreen, 10, 10); } /** diff --git a/src/classes/share/javax/media/j3d/ExceptionStrings.properties b/src/classes/share/javax/media/j3d/ExceptionStrings.properties index a556194..9e8b25b 100644 --- a/src/classes/share/javax/media/j3d/ExceptionStrings.properties +++ b/src/classes/share/javax/media/j3d/ExceptionStrings.properties @@ -137,6 +137,7 @@ Canvas3D19=Canvas3D: null GraphicsConfiguration Canvas3D20=Canvas3D does not support serialization Canvas3D21=*** ERROR: GraphicsConfiguration not created with GraphicsConfigTemplate3D Canvas3D22=*** This will cause an IllegalArgumentException in a subsequent release +Canvas3D23=Unable to get FBConfig from GraphicsConfiguration BoundingPolytope0=BoundingPolytope( Bounds) unrecognized bounds object BoundingPolytope1=BoundingPolytope( Bounds) unrecognized bounds type BoundingPolytope2=set( Bounds) unrecognized bounds type diff --git a/src/classes/share/javax/media/j3d/GraphicsContext3D.java b/src/classes/share/javax/media/j3d/GraphicsContext3D.java index 22d5fc0..e56d0ce 100644 --- a/src/classes/share/javax/media/j3d/GraphicsContext3D.java +++ b/src/classes/share/javax/media/j3d/GraphicsContext3D.java @@ -1580,7 +1580,7 @@ public class GraphicsContext3D extends Object { if (canvas3d.useSharedCtx) { if (canvas3d.screen.renderer.sharedCtx == 0) { synchronized (VirtualUniverse.mc.contextCreationLock) { - canvas3d.screen.renderer.sharedCtx = canvas3d.createContext( + canvas3d.screen.renderer.sharedCtx = canvas3d.createNewContext( canvas3d.screen.display, canvas3d.window, canvas3d.vid, 0, true, canvas3d.offScreen); @@ -1595,10 +1595,10 @@ public class GraphicsContext3D extends Object { if (canvas3d.ctx == 0) { synchronized (VirtualUniverse.mc.contextCreationLock) { canvas3d.ctx = - canvas3d.createContext(canvas3d.screen.display, + canvas3d.createNewContext(canvas3d.screen.display, canvas3d.window, canvas3d.vid, - canvas3d.visInfo, + canvas3d.fbConfig, 0, false, canvas3d.offScreen); if (canvas3d.ctx == 0) { diff --git a/src/classes/share/javax/media/j3d/Renderer.java b/src/classes/share/javax/media/j3d/Renderer.java index 3659f20..12b4dce 100644 --- a/src/classes/share/javax/media/j3d/Renderer.java +++ b/src/classes/share/javax/media/j3d/Renderer.java @@ -444,10 +444,14 @@ class Renderer extends J3dThread { if (renderType == J3dMessage.CREATE_OFFSCREENBUFFER) { // Fix for issue 18. + // Fix for issue 20. + /* System.out.println("Renderer offScreenBuffer - fbConfig = " + + canvas.fbConfig); */ canvas.window = canvas.createOffScreenBuffer(canvas.ctx, canvas.screen.display, - canvas.vid, + canvas.window, + canvas.fbConfig, canvas.offScreenCanvasSize.width, canvas.offScreenCanvasSize.height); m[nmesg++].decRefcount(); @@ -665,10 +669,10 @@ class Renderer extends J3dThread { synchronized (VirtualUniverse.mc.contextCreationLock) { sharedCtx = - canvas.createContext(canvas.screen.display, + canvas.createNewContext(canvas.screen.display, canvas.window, canvas.vid, - canvas.visInfo, + canvas.fbConfig, 0, true, canvas.offScreen); if (sharedCtx == 0) { @@ -704,9 +708,9 @@ class Renderer extends J3dThread { synchronized (VirtualUniverse.mc.contextCreationLock) { canvas.ctx = - canvas.createContext(canvas.screen.display, + canvas.createNewContext(canvas.screen.display, canvas.window, canvas.vid, - canvas.visInfo, sharedCtx, + canvas.fbConfig, sharedCtx, false, canvas.offScreen); @@ -1486,7 +1490,7 @@ class Renderer extends J3dThread { // we can safely execute destroyOffScreenBuffer. if(destroyOffScreenBuffer) { cv.makeCtxCurrent(); - cv.destroyOffScreenBuffer(ctx, display, window); + cv.destroyOffScreenBuffer(ctx, display, cv.fbConfig, window); } if (ctx != 0) { int idx = listOfCtxs.indexOf(new Long(ctx)); diff --git a/src/classes/solaris/javax/media/j3d/J3dGraphicsConfig.java b/src/classes/solaris/javax/media/j3d/J3dGraphicsConfig.java index f64843c..218bee8 100644 --- a/src/classes/solaris/javax/media/j3d/J3dGraphicsConfig.java +++ b/src/classes/solaris/javax/media/j3d/J3dGraphicsConfig.java @@ -29,9 +29,13 @@ class J3dGraphicsConfig { ((X11GraphicsConfig) gc).getVisual()); } - static boolean isValidConfig(GraphicsConfiguration gc) { - // Check to see if a valid visInfo pointer has been cached. - Object visInfoObject = Canvas3D.visInfoTable.get(gc); - return (visInfoObject != null) && (visInfoObject instanceof Long); + static boolean isValidConfig(GraphicsConfiguration gc) { + // Check to see if a valid fbConfig pointer has been cached. + Object fbConfigObject = Canvas3D.fbConfigTable.get(gc); + return ((fbConfigObject != null) && + (fbConfigObject instanceof Long)); + } + + } diff --git a/src/classes/solaris/javax/media/j3d/NativeConfigTemplate3D.java b/src/classes/solaris/javax/media/j3d/NativeConfigTemplate3D.java index b41266d..80d0dd9 100644 --- a/src/classes/solaris/javax/media/j3d/NativeConfigTemplate3D.java +++ b/src/classes/solaris/javax/media/j3d/NativeConfigTemplate3D.java @@ -26,7 +26,7 @@ class NativeConfigTemplate3D { VirtualUniverse.createMC(); } - // These definitions should match those in win32 NativeConfigTemplate3D.java + // These definitions should match those in win32 NativeConfigTemplate3D.java final static int RED_SIZE = 0; final static int GREEN_SIZE = 1; final static int BLUE_SIZE = 2; @@ -39,14 +39,14 @@ class NativeConfigTemplate3D { final static int NUM_ITEMS = 9; // Native method to get an OpenGL visual id and a pointer to the - // XVisualInfo struct itself. + // GLXFBConfig structure list itself. native int chooseOglVisual(long display, int screen, - int[] attrList, long[] visInfo); + int[] attrList, long[] fbConfig); - // Native method to free an XVisualInfo struct. This is static since it - // may need to be called to clean up the Canvas3D visInfoTable after the + // Native method to free an GLXFBConfig struct. This is static since it + // may need to be called to clean up the Canvas3D fbConfigTable after the // NativeConfigTemplate3D has been disposed of. - static native void freeVisual(long visInfo); + static native void freeFbConfig(long fbConfig); // Native methods to return whether a particular attribute is available native boolean isStereoAvailable(long display, int screen, int vid); @@ -55,8 +55,8 @@ class NativeConfigTemplate3D { native boolean isSceneAntialiasingMultiSamplesAvailable(long display, int screen, int vid); - /** - * Chooses the best visual for Java 3D apps. + /* + * Chooses the best FBConfig for Java 3D apps. */ GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate3D template, @@ -65,6 +65,10 @@ class NativeConfigTemplate3D { X11GraphicsDevice gd = (X11GraphicsDevice)((X11GraphicsConfig)gc[0]).getDevice(); + if (!NativeScreenInfo.isGLX13()) { + return null; + } + NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd); long display = nativeScreenInfo.getDisplay(); @@ -84,7 +88,7 @@ class NativeConfigTemplate3D { if ((bounds.x != 0 || bounds.y != 0) && (! VirtualUniverse.mc.xineramaDisabled)) { // Xinerama is being used. The screen needs to be set to 0 since - // glxChooseVisual will not return a valid visual otherwise. + // glxChooseFBConfig will not return a valid visual otherwise. screen = 0; if (debug) { System.out.println(" Non-primary Xinerama screen:"); @@ -94,7 +98,7 @@ class NativeConfigTemplate3D { } int[] attrList; // holds the list of attributes to be translated - // for glxChooseVisual call + // for glxChooseFBConfig call attrList = new int[NUM_ITEMS]; @@ -108,17 +112,17 @@ class NativeConfigTemplate3D { attrList[STEREO] = template.getStereo(); attrList[ANTIALIASING] = template.getSceneAntialiasing(); - long[] visInfo = new long[1]; - int visID = chooseOglVisual(display, screen, attrList, visInfo); + long[] fbConfig = new long[1]; + int visID = chooseOglVisual(display, screen, attrList, fbConfig); if (debug) { System.out.println(" chooseOglVisual() returns " + visID); - System.out.println(" pointer to XVisualInfo is " + visInfo[0]); + System.out.println(" pointer to GLXFBConfig is " + fbConfig[0]); System.out.println(); } - if (visID == 0 || visInfo[0] == 0) { + if (visID == 0 || fbConfig[0] == 0) { return null; // no valid visual was found - } + } // search list of graphics configurations for config // with matching visualId @@ -128,22 +132,22 @@ class NativeConfigTemplate3D { gc1 = gc[i]; break; } - + // To support disabling Solaris OpenGL Xinerama mode, we need to cache - // the pointer to the actual XVisualInfo that glXChooseVisual() + // the pointer to the actual GLXFBConfig that glXChooseFBConfig() // returns, since this is not cached with X11GraphicsConfig and there - // are no public constructors to allow us to extend it. - synchronized (Canvas3D.visInfoTable) { - if (Canvas3D.visInfoTable.get(gc1) == null) - Canvas3D.visInfoTable.put(gc1, new Long(visInfo[0])); + // are no public constructors to allow us to extend it. + synchronized (Canvas3D.fbConfigTable) { + if (Canvas3D.fbConfigTable.get(gc1) == null) + Canvas3D.fbConfigTable.put(gc1, new Long(fbConfig[0])); else - freeVisual(visInfo[0]); + freeFbConfig(fbConfig[0]); } return gc1; } - /** + /* * Determine if a given GraphicsConfiguration object can be used * by Java 3D. */ @@ -153,6 +157,10 @@ class NativeConfigTemplate3D { X11GraphicsDevice gd = (X11GraphicsDevice)((X11GraphicsConfig)gc).getDevice(); + if (!NativeScreenInfo.isGLX13()) { + return false; + } + NativeScreenInfo nativeScreenInfo = new NativeScreenInfo(gd); long display = nativeScreenInfo.getDisplay(); @@ -173,13 +181,13 @@ class NativeConfigTemplate3D { attrList[STEREO] = template.getStereo(); attrList[ANTIALIASING] = template.getSceneAntialiasing(); - long[] visInfo = new long[1]; - int visID = chooseOglVisual(display, screen, attrList, visInfo); - - if (visID == 0 || visInfo[0] == 0) - return false; // no valid visual was found + long[] fbConfig = new long[1]; + int visID = chooseOglVisual(display, screen, attrList, fbConfig); + + if (visID == 0 || fbConfig[0] == 0) + return false; // no valid visual was found else - return true; + return true; } diff --git a/src/classes/solaris/javax/media/j3d/NativeScreenInfo.java b/src/classes/solaris/javax/media/j3d/NativeScreenInfo.java index a88091b..19c8967 100644 --- a/src/classes/solaris/javax/media/j3d/NativeScreenInfo.java +++ b/src/classes/solaris/javax/media/j3d/NativeScreenInfo.java @@ -18,9 +18,27 @@ import sun.awt.X11GraphicsDevice; class NativeScreenInfo { private int screen; private static long display = 0; + private static boolean glxChecked = false; + private static boolean isGLX13; private native static long openDisplay(); private native static int getDefaultScreen(long display); + private native static boolean queryGLX13(long display); + + // Fix for issue 20. + // This method will return true if glx version is 1.3 or higher, + // else return false. + synchronized static boolean isGLX13() { + if (!glxChecked) { + // Open a new static display connection if one is not already opened. + getStaticDisplay(); + // Query for glx1.3 support. + isGLX13 = queryGLX13(display); + glxChecked = true; + } + + return isGLX13; + } synchronized static long getStaticDisplay() { if (display == 0) { diff --git a/src/native/d3d/Canvas3D.cpp b/src/native/d3d/Canvas3D.cpp index c262335..2e5eea2 100644 --- a/src/native/d3d/Canvas3D.cpp +++ b/src/native/d3d/Canvas3D.cpp @@ -46,13 +46,13 @@ jboolean JNICALL Java_javax_media_j3d_Canvas3D_useSharedCtx( extern "C" JNIEXPORT -jlong JNICALL Java_javax_media_j3d_Canvas3D_createContext( +jlong JNICALL Java_javax_media_j3d_Canvas3D_createNewContext( JNIEnv *env, jobject obj, jlong display, jint window, jint vid, - jlong visInfo, + jlong fbConfigListPtr, jlong sharedCtx, jboolean isSharedCtx, jboolean offScreen) @@ -106,6 +106,7 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( jlong display, jint window, jint vid, + jlong fbConfigListPtr, jboolean offScreen, jint width, jint height) @@ -821,7 +822,8 @@ jint JNICALL Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( jobject obj, jlong ctx, jlong display, - jint vid, + jint window, + jlong fbConfigListPtr, jint width, jint height) { @@ -864,6 +866,7 @@ void JNICALL Java_javax_media_j3d_Canvas3D_destroyOffScreenBuffer( jobject obj, jlong ctx, jlong display, + jlong fbConfigListPtr, jint window) { // do nothing, since the old buffer will destory diff --git a/src/native/ogl/Canvas3D.c b/src/native/ogl/Canvas3D.c index 146d531..ab8f1db 100644 --- a/src/native/ogl/Canvas3D.c +++ b/src/native/ogl/Canvas3D.c @@ -423,7 +423,7 @@ BOOL getPropertiesFromCurrentContext( jlong hdc, int pixelFormat, long display, - jlong vinfo) + int stencilSize) { JNIEnv table = *env; @@ -434,7 +434,7 @@ BOOL getPropertiesFromCurrentContext( char *tmpExtensionStr; int versionNumbers[2]; char *cgHwStr = 0; - int stencilSize; + #ifdef WIN32 PFNWGLGETPIXELFORMATATTRIBIVEXTPROC wglGetPixelFormatAttribivEXT = NULL; @@ -942,10 +942,8 @@ BOOL getPropertiesFromCurrentContext( ctxInfo->global_alpha_sun = JNI_FALSE; } } - - glXGetConfig((Display *) display, (XVisualInfo *) vinfo, GLX_STENCIL_SIZE, &stencilSize); -#endif +#endif /* Solaris or Linux */ if (stencilSize > 1) { ctxInfo->extMask |= javax_media_j3d_Canvas3D_STENCIL_BUFFER; @@ -1081,33 +1079,46 @@ LONG WINAPI WndProc( HWND hWnd, UINT msg, #endif /*end of WIN32 */ - - JNIEXPORT -jlong JNICALL Java_javax_media_j3d_Canvas3D_createContext( +jlong JNICALL Java_javax_media_j3d_Canvas3D_createNewContext( JNIEnv *env, jobject obj, jlong display, jint window, jint vid, - jlong visInfo, + jlong fbConfigListPtr, jlong sharedCtxInfo, jboolean isSharedCtx, jboolean offScreen) { jlong gctx; jlong sharedCtx; - + int stencilSize=0; + static GLboolean first_time = GL_TRUE; static GLboolean force_normalize = GL_FALSE; GraphicsContextPropertiesInfo *ctxInfo = NULL; GraphicsContextPropertiesInfo *sharedCtxStructure; int PixelFormatID=0; - + #if defined(SOLARIS) || defined(__linux__) + + /* Fix for issue 20 */ + GLXContext ctx; jlong hdc; + + GLXFBConfig *fbConfigList = NULL; + + fbConfigList = (GLXFBConfig *)fbConfigListPtr; + + /* + fprintf(stderr, "Canvas3D_createNewContext: \n"); + fprintf(stderr, "fbConfigListPtr 0x%x\n", (int) fbConfigListPtr); + fprintf(stderr, "fbConfigList 0x%x, fbConfigList[0] 0x%x\n", + (int) fbConfigList, (int) fbConfigList[0]); + */ if(sharedCtxInfo == 0) sharedCtx = 0; @@ -1117,37 +1128,47 @@ jlong JNICALL Java_javax_media_j3d_Canvas3D_createContext( } if (display == 0) { - fprintf(stderr, "Canvas3D_createContext: display is null\n"); + fprintf(stderr, "Canvas3D_createNewContext: display is null\n"); ctx = NULL; } - else if (visInfo == 0) { + else if((fbConfigList == NULL) || (fbConfigList[0] == NULL)) { /* - * visInfo must be a valid pointer to an XVisualInfo struct returned - * by glXChooseVisual() for a physical screen. The visual id in vid + * fbConfig must be a valid pointer to an GLXFBConfig struct returned + * by glXChooseFBConfig() for a physical screen. The visual id in vid * is not sufficient for handling OpenGL with Xinerama mode disabled: * it doesn't distinguish between the physical screens making up the * virtual screen when the X server is running in Xinerama mode. */ - fprintf(stderr, "Canvas3D_createContext: visual is null\n"); + fprintf(stderr, "Canvas3D_createNewContext: FBConfig is null\n"); ctx = NULL; } else { - ctx = glXCreateContext((Display *)display, (XVisualInfo *)visInfo, - (GLXContext)sharedCtx, True); + ctx = glXCreateNewContext((Display *)display, fbConfigList[0], + GLX_RGBA_TYPE, (GLXContext)sharedCtx, True); } - if (ctx == NULL) { - fprintf(stderr, "Canvas3D_createContext: couldn't create context\n"); + fprintf(stderr, "Canvas3D_createNewContext: couldn't create context\n"); return 0; } - if (!glXMakeCurrent((Display *)display, (GLXDrawable)window, - (GLXContext)ctx)) { - fprintf( stderr, "Canvas3D_createContext: couldn't make current\n"); + /* There is a known interportability issue between Solaris and Linux(Nvidia) + on the new glxMakeContextCurrent() call. Bug Id 5109045. + if (!glXMakeContextCurrent((Display *)display, (GLXDrawable)window, + (GLXDrawable)window,(GLXContext)ctx)) { + */ + + if (!glXMakeCurrent((Display *)display, (GLXDrawable)window,(GLXContext)ctx)) { + + fprintf( stderr, "Canvas3D_createNewContext: couldn't make current\n"); return 0; } + + glXGetFBConfigAttrib((Display *) display, fbConfigList[0], + GLX_STENCIL_SIZE, &stencilSize); + + gctx = (jlong)ctx; #endif /* SOLARIS */ @@ -1219,7 +1240,6 @@ jlong JNICALL Java_javax_media_j3d_Canvas3D_createContext( PixelFormatID = vid; } - SetPixelFormat(hdc, PixelFormatID, &pfd); hrc = wglCreateContext( hdc ); @@ -1257,9 +1277,10 @@ jlong JNICALL Java_javax_media_j3d_Canvas3D_createContext( /* initialize the structure */ initializeCtxInfo(env, ctxInfo); - ctxInfo->context = gctx; - - if (!getPropertiesFromCurrentContext(env, obj, ctxInfo, (jlong) hdc, PixelFormatID, display, (jlong) visInfo)) { + ctxInfo->context = gctx; + + if (!getPropertiesFromCurrentContext(env, obj, ctxInfo, (jlong) hdc, PixelFormatID, + display, stencilSize)) { return 0; } @@ -2546,57 +2567,6 @@ int getTextureColorTableSize( return size; } -/* we want to use this if available: */ -#define GLX_SGIX_pbuffer 1 - -#ifndef GLX_VERSION_1_3 -#ifdef GLX_SGIX_pbuffer -#ifdef __linux__ -typedef XID GLXPbuffer; -typedef struct __GLXFBConfigRec *GLXFBConfig; -typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; -extern GLXFBConfig * glXChooseFBConfig (Display *dpy, int screen, const int *attrib_list, int *nelements); -extern GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int *attrib_list); -extern void glXDestroyPbuffer (Display *dpy, GLXPbuffer pbuf); -extern GLXFBConfigSGIX *glXChooseFBConfigSGIX(Display *dpy, int screen, const int *attribList, int *nitems); -extern GLXPbuffer glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfig config, unsigned int width, unsigned int height, const int *attribList); -extern void glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbuffer pbuf); -#define GLX_DRAWABLE_TYPE 0x8010 -#define GLX_PBUFFER_BIT 0x00000004 -#define GLX_RENDER_TYPE 0x8011 -#define GLX_RGBA_BIT 0x00000001 -#define GLX_MAX_PBUFFER_WIDTH 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT 0x8017 -#define GLX_PRESERVED_CONTENTS 0x801B -#define GLX_PBUFFER_HEIGHT 0x8040 /* New for GLX 1.3 */ -#define GLX_PBUFFER_WIDTH 0x8041 /* New for GLX 1.3 */ -#define GLX_LARGEST_PBUFFER 0x801C -#define GLX_LARGEST_PBUFFER_SGIX GLX_LARGEST_PBUFFER -#else - -#define GLX_DRAWABLE_TYPE GLX_DRAWABLE_TYPE_SGIX -#define GLX_PBUFFER_BIT GLX_PBUFFER_BIT_SGIX -#define GLX_RENDER_TYPE GLX_RENDER_TYPE_SGIX -#define GLX_RGBA_BIT GLX_RGBA_BIT_SGIX -#endif -#endif /* GLX_SGIX_pbuffer */ -#else -#ifdef __linux__ -typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; -#endif /* __linux__ */ -#endif /* GLX_VERSION_1_3 */ - -#if defined(SOLARIS) || defined(__linux__) -#pragma weak glXChooseFBConfig -#pragma weak glXCreatePbuffer -#pragma weak glXDestroyPbuffer -#pragma weak glXChooseFBConfigSGIX -#pragma weak glXCreateGLXPbufferSGIX -#pragma weak glXDestroyGLXPbufferSGIX -#endif /* SOLARIS */ - - - /* For dvr support */ JNIEXPORT void JNICALL Java_javax_media_j3d_Canvas3D_videoResize( @@ -2650,146 +2620,121 @@ jint JNICALL Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( jobject obj, jlong ctxInfo, jlong display, - jint vid, + jint window, + jlong fbConfigListPtr, jint width, jint height) { #if defined(SOLARIS) || defined(__linux__) - XVisualInfo *vinfo, template; - int nitems, depth, redSize; - Display *dpy; - static GLboolean pbufferSupported = GL_FALSE; - static GLboolean pbufferExtSupported = GL_FALSE; - int major, minor; - const char *extStr; - int status; - dpy = (Display *)display; + /* Fix for issue 20 */ + + const char *extStr; + int attrCount, configAttr[10]; + GLXPbuffer pbuff = None; + GLXFBConfig *fbConfigList = (GLXFBConfig *)fbConfigListPtr; + int val; + + /* + glXGetFBConfigAttrib((Display *) display, fbConfigList[0], + GLX_FBCONFIG_ID, &val); + fprintf(stderr, "GLX_FBCONFIG_ID returns %d\n", val); + + fprintf(stderr, "display 0x%x, fbConfigList[0] 0x%x, width %d, height %d\n", + (int) display, (int) fbConfigList[0], width, height); + + */ - if (dpy == NULL) - dpy = XOpenDisplay(NULL); + + /* Query DRAWABLE_TYPE. Will use Pbuffer if fbConfig support it, + else will try for Pixmap. If neither one exists, flag error message + and return None */ + + glXGetFBConfigAttrib((Display *) display, fbConfigList[0], + GLX_DRAWABLE_TYPE, &val); + /* fprintf(stderr, "GLX_DRAWABLE_TYPE returns %d\n", val); */ + + if ((val & GLX_PBUFFER_BIT) != 0) { - template.visualid = vid; - vinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &nitems); - if (nitems != 1) { - fprintf(stderr, "Warning Canvas3D_createContext got unexpected number of matching visuals %d\n", nitems); - } - glXGetConfig (dpy, vinfo, GLX_BUFFER_SIZE, &depth); - glXGetConfig (dpy, vinfo, GLX_RED_SIZE, &redSize); + /* fprintf(stderr, "Using pbuffer %d\n", val); */ + + /* Initialize the attribute list to be used for choosing FBConfig */ + + attrCount = 0; + configAttr[attrCount++] = GLX_PBUFFER_WIDTH; + configAttr[attrCount++] = width; + configAttr[attrCount++] = GLX_PBUFFER_HEIGHT; + configAttr[attrCount++] = height; + configAttr[attrCount++] = GLX_PRESERVED_CONTENTS; + configAttr[attrCount++] = GL_TRUE; + configAttr[attrCount++] = None; + - if (status = glXQueryVersion(dpy, &major, &minor)) { + pbuff = glXCreatePbuffer((Display *) display, fbConfigList[0], configAttr); + + if (pbuff == None) { + fprintf(stderr, "Java 3D ERROR : glXCreateGLXPbuffer() returns None\n"); + } -#if 0 - /* don't use the 1.3 pbuffer interface for now. */ - if ((major > 1) || (major == 1 && minor >= 3)) - pbufferSupported = GL_TRUE; - else -#endif - { - extStr = glXQueryExtensionsString(dpy, DefaultScreen(dpy)); - if ((extStr != NULL) && (strstr(extStr, "GLX_SGIX_pbuffer"))) { - pbufferExtSupported = GL_TRUE; - } - } + return pbuff; } + else if((val & GLX_PIXMAP_BIT) != 0) { + Pixmap pixmap; + GLXPixmap glxpixmap = None; + XVisualInfo *vinfo; + Window root; + Window glWin; + XSetWindowAttributes win_attrs; + Colormap cmap; + unsigned long win_mask; + + /* fprintf(stderr, "Using pixmap %d\n", val); */ + vinfo = glXGetVisualFromFBConfig((Display*)display, fbConfigList[0]); + if (vinfo == NULL) { + fprintf(stderr, "Java 3D ERROR : glXGetVisualFromFBConfig failed\n"); + } + else { + /* fprintf(stderr, "found a %d-bit visual (visual ID = 0x%x)\n", + vinfo->depth, vinfo->visualid); */ + + /* fall back to pixmap */ + root = RootWindow((Display *)display, vinfo->screen); + + /* Create a colormap */ + cmap = XCreateColormap((Display *)display, root, vinfo->visual, AllocNone); + + /* Create a window */ + win_attrs.colormap = cmap; + win_attrs.border_pixel = 0; + win_mask = CWColormap | CWBorderPixel; + glWin = XCreateWindow((Display *)display, root, 0, 0, 1, 1, 0, + vinfo->depth, InputOutput, vinfo->visual, + win_mask, &win_attrs); + + /* fprintf(stderr, "glWin %d\n",(int) glWin); */ + + pixmap = XCreatePixmap((Display*)display, (GLXDrawable)glWin, + width, height, vinfo->depth); + + /* fprintf(stderr, "XCreatePixmap returns %d\n", (int) pixmap); */ + + glxpixmap = glXCreatePixmap((Display*)display, fbConfigList[0], pixmap, NULL); + if (glxpixmap == None) { + fprintf(stderr, "Java 3D ERROR : glXCreateGLXPixmap() returns None\n"); + } + } -#if defined(GLX_VERSION_1_3) || defined(GLX_SGIX_pbuffer) - if (pbufferExtSupported || pbufferSupported) { - - - int attrCount, configAttr[10], numConfig, val; - GLXPbuffer pbuff; - - /* Initialize the attribute list to be used for choosing FBConfig */ - attrCount = 0; - configAttr[attrCount++] = GLX_DRAWABLE_TYPE; - configAttr[attrCount++] = GLX_PBUFFER_BIT; - configAttr[attrCount++] = GLX_RENDER_TYPE; - configAttr[attrCount++] = GLX_RGBA_BIT; - configAttr[attrCount++] = GLX_RED_SIZE; - configAttr[attrCount++] = redSize; - configAttr[attrCount++] = None; -/* - configAttr[attrCount++] = GLX_DEPTH_SIZE; - configAttr[attrCount++] = depth; -*/ - - -#ifdef GLX_VERSION_1_3 - if (pbufferSupported) { - GLXFBConfig *fbconfiglst; - - fbconfiglst = glXChooseFBConfig(dpy, DefaultScreen(dpy), - configAttr, &numConfig); - - if (numConfig < 1) { - fprintf(stderr, "# of configs returned is %d\n", numConfig); - return None; - } - - attrCount = 0; - configAttr[attrCount++] = GLX_PBUFFER_WIDTH; - configAttr[attrCount++] = width; - configAttr[attrCount++] = GLX_PBUFFER_HEIGHT; - configAttr[attrCount++] = height; - configAttr[attrCount++] = GLX_PRESERVED_CONTENTS; - configAttr[attrCount++] = GL_TRUE; - configAttr[attrCount++] = None; - - - pbuff = glXCreatePbuffer(dpy, fbconfiglst[0], configAttr); - } -#endif /* GLX_VERSION_1_3 */ - -#ifdef GLX_SGIX_pbuffer - if (pbufferExtSupported && !pbufferSupported) { - GLXFBConfigSGIX *fbconfiglst; - - - /* Determine what config to use according to config_attr */ - fbconfiglst = glXChooseFBConfigSGIX(dpy, DefaultScreen(dpy), - configAttr, &numConfig); - - if (numConfig < 1) { - fprintf(stderr, "# of configs returned is %d\n", numConfig); - return None; - } - - attrCount = 0; - configAttr[attrCount++] = GLX_PRESERVED_CONTENTS; - configAttr[attrCount++] = GL_TRUE; - configAttr[attrCount++] = None; - pbuff = glXCreateGLXPbufferSGIX(dpy, fbconfiglst[0], width, height, - configAttr ); - } -#endif /* GLX_SGIX_pbuffer */ - if (pbuff == None) { - fprintf(stderr, "glXCreateGLXPbuffer() returns None\n"); - } - - return pbuff; - - } else -#endif /* GLX_VERSION_1_3 || GLX_SGIX_pbuffer */ - - { - Pixmap pixmap; - GLXPixmap glxpixmap; - - /* fall back to pixmap */ - pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), width, height, - vinfo->depth); - - glxpixmap = glXCreateGLXPixmap(dpy, vinfo, pixmap); - if (glxpixmap == None) { - fprintf(stderr, "glXCreateGLXPixmap() returns None\n"); - } - - return glxpixmap; + /* fprintf(stderr, "glxpixmap %d\n",(int) glxpixmap); */ + return glxpixmap; + } + else { + fprintf(stderr, "Java 3D ERROR : FBConfig doesn't support pbuffer or pixmap returns None\n"); + return None; } + #endif /* SOLARIS */ #ifdef WIN32 @@ -2857,45 +2802,25 @@ void JNICALL Java_javax_media_j3d_Canvas3D_destroyOffScreenBuffer( jobject obj, jlong ctxInfo, jlong display, + jlong fbConfigListPtr, jint window) { #if defined(SOLARIS) || defined(__linux__) - Display *dpy = (Display*)display; - - GLboolean pbufferSupported = GL_FALSE; - GLboolean pbufferExtSupported = GL_TRUE; - int major, minor; - char *extStr; - - if (glXQueryVersion(dpy, &major, &minor)) { - -#if 0 - /* don't use the 1.3 pbuffer interface for now. */ - if ((major > 1) || (major == 1 && minor >= 3)) - pbufferSupported = GL_TRUE; - else -#endif - { - extStr = (char *)glXQueryExtensionsString(dpy, - DefaultScreen(dpy)); - if ((extStr != NULL) && (strstr(extStr, "GLX_SGIX_pbuffer"))) { - pbufferExtSupported = GL_TRUE; - } - } - } - -#if defined(GLX_VERSION_1_3) || defined(GLX_SGIX_pbuffer) - - if (pbufferSupported) { - glXDestroyPbuffer(dpy, (GLXPbuffer)window); - } else if (pbufferExtSupported) { - glXDestroyGLXPbufferSGIX(dpy, (GLXPbuffer)window); - } else -#endif - - { - glXDestroyGLXPixmap(dpy, (GLXPixmap)window); - } + /* Fix for Issue 20 */ + GLXFBConfig *fbConfigList = (GLXFBConfig *)fbConfigListPtr; + int val; + + glXGetFBConfigAttrib((Display *) display, (GLXFBConfig) fbConfigList[0], + GLX_DRAWABLE_TYPE, &val); + /* fprintf(stderr, "GLX_DRAWABLE_TYPE returns %d\n", val); */ + + if((val & GLX_PBUFFER_BIT) != 0) { + glXDestroyPbuffer((Display *) display, (GLXPbuffer)window); + } + else if((val & GLX_PIXMAP_BIT) != 0) { + glXDestroyPixmap((Display *) display, (GLXPixmap)window); + } + #endif /* SOLARIS */ #ifdef WIN32 @@ -3159,17 +3084,22 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( jlong display, jint window, jint vid, + jlong fbConfigListPtr, jboolean offScreen, jint width, jint height) { JNIEnv table = *env; jlong gctx; + int stencilSize=0; long newWin; int PixelFormatID=0; GraphicsContextPropertiesInfo* ctxInfo = (GraphicsContextPropertiesInfo *)malloc(sizeof(GraphicsContextPropertiesInfo)); #if defined(SOLARIS) || defined(__linux__) + + /* Fix for issue 20 */ + XVisualInfo *vinfo, template; int nitems; GLXContext ctx; @@ -3180,46 +3110,71 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( Colormap cmap; unsigned long win_mask; jlong hdc; + + GLXFBConfig *fbConfigList = NULL; - template.visualid = vid; - vinfo = XGetVisualInfo((Display *)display, VisualIDMask, &template, &nitems); - if (nitems != 1) { - fprintf(stderr, "Warning Canvas3D_createQueryContext got unexpected number of matching visuals %d\n", nitems); - } + fbConfigList = (GLXFBConfig *)fbConfigListPtr; - ctx = glXCreateContext((Display *)display, vinfo, NULL, True); + /* + fprintf(stderr, "Canvas3D_createQueryContext:\n"); + fprintf(stderr, "fbConfigListPtr 0x%x\n", (int) fbConfigListPtr); + fprintf(stderr, "fbConfigList 0x%x, fbConfigList[0] 0x%x\n", + (int) fbConfigList, (int) fbConfigList[0]); + */ + + ctx = glXCreateNewContext((Display *)display, fbConfigList[0], + GLX_RGBA_TYPE, NULL, True); + if (ctx == NULL) { - fprintf(stderr, "Error Canvas3D_createQueryContext: couldn't create context.\n"); + fprintf(stderr, "Java 3D ERROR : Canvas3D_createQueryContext: couldn't create context.\n"); } /* create window if window == 0 and offscreen == true */ if(window == 0 && !offScreen) { - - root = RootWindow((Display *)display, vinfo->screen); - - /* Create a colormap */ - cmap = XCreateColormap((Display *)display, root, vinfo->visual, AllocNone); - /* Create a window */ - win_attrs.colormap = cmap; - win_attrs.border_pixel = 0; - win_attrs.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask; - win_mask = CWColormap | CWBorderPixel | CWEventMask; - glWin = XCreateWindow((Display *)display, root, 0, 0, width, height, 0, vinfo->depth, - InputOutput, vinfo->visual, win_mask, &win_attrs); - newWin = (unsigned long)glWin; + vinfo = glXGetVisualFromFBConfig((Display*)display, fbConfigList[0]); + if (vinfo == NULL) { + fprintf(stderr, "Java 3D ERROR : glXGetVisualFromFBConfig failed\n"); + } + else { + /* fprintf(stderr, "found a %d-bit visual (visual ID = 0x%x)\n", + vinfo->depth, vinfo->visualid); + */ + root = RootWindow((Display *)display, vinfo->screen); + + /* Create a colormap */ + cmap = XCreateColormap((Display *)display, root, vinfo->visual, AllocNone); + + /* Create a window */ + win_attrs.colormap = cmap; + win_attrs.border_pixel = 0; + win_attrs.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask; + win_mask = CWColormap | CWBorderPixel | CWEventMask; + glWin = XCreateWindow((Display *)display, root, 0, 0, width, height, 0, + vinfo->depth, InputOutput, vinfo->visual, + win_mask, &win_attrs); + newWin = (unsigned long)glWin; + } } else if(window == 0 && offScreen){ - newWin = Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( env, obj, 0, display, vid, width, height); + newWin = Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( env, obj, 0, + display, window, + fbConfigListPtr, + width, height); } else if(window != 0) { newWin = window; } - + result = glXMakeCurrent((Display *)display, (GLXDrawable)newWin, (GLXContext)ctx); if (result == GL_FALSE) - fprintf(stderr, "glXMakeCurrent fails\n"); + fprintf(stderr, "Java 3D ERROR : glXMakeCurrent fails\n"); + + glXGetFBConfigAttrib((Display *) display, fbConfigList[0], + GLX_STENCIL_SIZE, &stencilSize); + + gctx = (jlong)ctx; #endif @@ -3264,7 +3219,8 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( hdc = GetDC(hWnd); } else if(window == 0 && offScreen){ - hdc = (HDC)Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( env, obj, 0, display, vid, width, height); + hdc = (HDC)Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( env, obj, 0, display, + window, vid, width, height); pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI; vid = -1; @@ -3329,7 +3285,8 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( ctxInfo->context = gctx; /* get current context properties */ - if (getPropertiesFromCurrentContext(env, obj, ctxInfo, (jlong) hdc, PixelFormatID, display, (jlong) vinfo)) { + if (getPropertiesFromCurrentContext(env, obj, ctxInfo, (jlong) hdc, PixelFormatID, display, + stencilSize)) { /* put the properties to the Java side */ setupCanvasProperties(env, obj, ctxInfo); } @@ -3353,7 +3310,7 @@ void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( #endif /* WIN32 */ } else if(window == 0 && offScreen) { - Java_javax_media_j3d_Canvas3D_destroyOffScreenBuffer(env, obj, gctx, display, newWin); + Java_javax_media_j3d_Canvas3D_destroyOffScreenBuffer(env, obj, gctx, display, fbConfigListPtr, newWin); Java_javax_media_j3d_Canvas3D_destroyContext(env, obj, display, newWin, (jlong)ctxInfo); } else if(window != 0){ diff --git a/src/native/ogl/NativeConfigTemplate3D.c b/src/native/ogl/NativeConfigTemplate3D.c index ae2340f..4dbbfaa 100644 --- a/src/native/ogl/NativeConfigTemplate3D.c +++ b/src/native/ogl/NativeConfigTemplate3D.c @@ -37,151 +37,210 @@ extern int isExtensionSupported(const char *allExtensions, const char *extension #if defined(SOLARIS) || defined(__linux__) -XVisualInfo *findVisualInfoSwitchDoubleBufferAndStereo(jlong display, - jint screen, - int* glxAttrs, - int sVal, int sIndex, - int dbVal, int dbIndex ) { - int stereoLoop; - int doubleBufferLoop; - XVisualInfo *vis_info = NULL; - - int i, j; - /* - * set all "enums" to user's preferred state - */ - if (dbVal == REQUIRED || dbVal == PREFERRED) - glxAttrs[dbIndex] = GLX_DOUBLEBUFFER; - else - glxAttrs[dbIndex] = GLX_USE_GL; +/* Fix for issue 20 */ +#define MAX_GLX_ATTRS_LENGTH 25 - if (sVal == REQUIRED || sVal == PREFERRED) - glxAttrs[sIndex] = GLX_STEREO; - else - glxAttrs[sIndex] = GLX_USE_GL; - - vis_info = glXChooseVisual((Display*)display, screen, glxAttrs); - if (vis_info == NULL) { - /* - * coudn't match visual with default values - try - * enabling UNNECESSARY attributes. - */ - if(sVal == UNNECESSARY) - stereoLoop = 1; - else - stereoLoop = 0; - - if(dbVal == UNNECESSARY) - doubleBufferLoop = 1; - else - doubleBufferLoop = 0; +GLXFBConfig *find_S_FBConfigs(jlong display, + jint screen, + int* glxAttrs, + int sVal, int sIndex) { + + GLXFBConfig *fbConfigList = NULL; + int numFBConfigs, index; + + J3D_ASSERT((sIndex+3) < MAX_GLX_ATTRS_LENGTH); + + if (sVal == REQUIRED || sVal== PREFERRED) { + + index = sIndex; + glxAttrs[index++] = GLX_STEREO; + glxAttrs[index++] = True; + glxAttrs[index] = None; - i = 0; - while(i <= stereoLoop && vis_info == NULL ) { - if (sVal == UNNECESSARY) - glxAttrs[sIndex] = i? GLX_STEREO : GLX_USE_GL; - j = 0; - while(j <= doubleBufferLoop && vis_info == NULL) { - if(dbVal == UNNECESSARY) { - glxAttrs[dbIndex] = j? GLX_USE_GL: GLX_DOUBLEBUFFER; - } - vis_info = glXChooseVisual((Display*)display, screen, glxAttrs); - j++; - } /* end of doubleBufferLoop */ - i++; - } /* end of stereoLoop */ + fbConfigList = glXChooseFBConfig((Display*)display, screen, + glxAttrs, &numFBConfigs); + + if(fbConfigList != NULL) { + return fbConfigList; + } } + + if (sVal == UNNECESSARY || sVal== PREFERRED) { + /* This is a workaround to BugId : 5106472 in Solaris OGL. + We can't set glxAttrs with GLX_STEREO follow by a boolean */ - if (vis_info == NULL) { - /* - * still coudn't match visual with default values - try - * disabling PREFERRED attributes. - */ - /* restore default values */ - if (sVal == REQUIRED || sVal == PREFERRED) - glxAttrs[sIndex] = GLX_STEREO; - else - glxAttrs[sIndex] = GLX_USE_GL; - - if (dbVal == REQUIRED || dbVal == PREFERRED) - glxAttrs[dbIndex] = GLX_DOUBLEBUFFER; - else - glxAttrs[dbIndex] = GLX_USE_GL; - - if(sVal == PREFERRED) - stereoLoop = 1; - else - stereoLoop = 0; + index = sIndex; + glxAttrs[index] = None; - if(dbVal == PREFERRED) - doubleBufferLoop = 1; - else - doubleBufferLoop = 0; + /* For debug only + { + int i=0; + fprintf(stderr, "find_S_FBConfigs sVal = %d\n", sVal); + + while(glxAttrs[i] != None) { + fprintf(stderr, "glxAttrs[%d] = %x", i, glxAttrs[i]); + i++; + fprintf(stderr, " glxAttrs[%d] = %x\n", i, glxAttrs[i]); + i++; + } + } + */ + fbConfigList = glXChooseFBConfig((Display*)display, screen, + glxAttrs, &numFBConfigs); - i = 0; - while(i <= stereoLoop && vis_info == NULL ) { - if (sVal == PREFERRED) - glxAttrs[sIndex] = i? GLX_USE_GL : GLX_STEREO ; - j = 0; - while(j <= doubleBufferLoop && vis_info == NULL) { - if(dbVal == PREFERRED) { - glxAttrs[dbIndex] = j? GLX_DOUBLEBUFFER : GLX_USE_GL; - } - vis_info = glXChooseVisual((Display*)display, screen, glxAttrs); - j++; - } /* end of doubleBufferLoop */ - i++; - } /* end of stereoLoop */ + if(fbConfigList != NULL) { + return fbConfigList; + } } - if (vis_info == NULL) { + if (sVal == UNNECESSARY) { + index = sIndex; + glxAttrs[index++] = GLX_STEREO; + glxAttrs[index++] = True; + glxAttrs[index] = None; + + fbConfigList = glXChooseFBConfig((Display*)display, screen, + glxAttrs, &numFBConfigs); + + if(fbConfigList != NULL) { + return fbConfigList; + } + } + + return NULL; +} + +GLXFBConfig *find_AA_S_FBConfigs(jlong display, + jint screen, + int* glxAttrs, + int sVal, + int antialiasVal, int antialiasIndex) { + + const char *glxExtensions = NULL; + GLXFBConfig *fbConfigList = NULL; + int index = antialiasIndex; + + + J3D_ASSERT((antialiasIndex+7) < MAX_GLX_ATTRS_LENGTH); + + if(antialiasVal == REQUIRED || antialiasVal== PREFERRED) { + glxExtensions = (const char *) glXGetClientString((Display*)display, GLX_EXTENSIONS); + + if(isExtensionSupported(glxExtensions, "GLX_ARB_multisample")){ + + index = antialiasIndex; + glxAttrs[index++] = GLX_SAMPLE_BUFFERS_ARB; + glxAttrs[index++] = 1; + glxAttrs[index++] = GLX_SAMPLES_ARB; + glxAttrs[index++] = 1; + glxAttrs[index] = None; - /* - * STILL coudn't match visual with default values - try - * disabling PREFERRED attributes and enabling UNNECESSARY. - */ + fbConfigList = find_S_FBConfigs(display, screen, + glxAttrs, sVal, index); + + if(fbConfigList != NULL) { + return fbConfigList; + } + } + } + + if ( antialiasVal == REQUIRED ) { + index = antialiasIndex; + glxAttrs[index++] = GLX_ACCUM_RED_SIZE; + glxAttrs[index++] = 8; + glxAttrs[index++] = GLX_ACCUM_GREEN_SIZE; + glxAttrs[index++] = 8; + glxAttrs[index++] = GLX_ACCUM_BLUE_SIZE; + glxAttrs[index++] = 8; + glxAttrs[index] = None; - /* restore default values */ - if (sVal == REQUIRED || sVal == PREFERRED) - glxAttrs[sIndex] = GLX_STEREO; - else - glxAttrs[sIndex] = GLX_USE_GL; - - if (dbVal == REQUIRED || dbVal == PREFERRED) - glxAttrs[dbIndex] = GLX_DOUBLEBUFFER; - else - glxAttrs[dbIndex] = GLX_USE_GL; - - if(sVal != REQUIRED) - stereoLoop = 1; - else - stereoLoop = 0; + fbConfigList = find_S_FBConfigs(display, screen, + glxAttrs, sVal, index); - if(dbVal != REQUIRED) - doubleBufferLoop = 1; - else - doubleBufferLoop = 0; - - i = 0; - while(i <= stereoLoop && vis_info == NULL ) { - if (sVal == PREFERRED || sVal == UNNECESSARY) - glxAttrs[sIndex] = i? GLX_USE_GL : GLX_STEREO ; - j = 0; - while(j <= doubleBufferLoop && vis_info == NULL) { - if(dbVal == PREFERRED || dbVal == UNNECESSARY) { - glxAttrs[dbIndex] = j? GLX_DOUBLEBUFFER : GLX_USE_GL; - } - vis_info = glXChooseVisual((Display*)display, screen, glxAttrs); - j++; - } /* end of doubleBufferLoop */ - i++; - } /* end of stereoLoop */ + if(fbConfigList != NULL) { + return fbConfigList; + } + } + + glxAttrs[antialiasIndex] = None; + + if (antialiasVal == UNNECESSARY || antialiasVal == PREFERRED) { + fbConfigList = find_S_FBConfigs(display, screen, + glxAttrs, sVal, index); + + if(fbConfigList != NULL) { + return fbConfigList; + } + } + /* We will stop trying even if no fbConfigList is found and + antialiasVal = UNNECESSARY */ + + return NULL; + +} + +GLXFBConfig *find_DB_AA_S_FBConfigs(jlong display, + jint screen, + int* glxAttrs, + int sVal, int dbVal, + int antialiasVal, int dbIndex) { + + GLXFBConfig *fbConfigList = NULL; + int index = dbIndex; + + J3D_ASSERT((dbIndex+3) < MAX_GLX_ATTRS_LENGTH); + + if (dbVal == REQUIRED || dbVal== PREFERRED) { + + index = dbIndex; + glxAttrs[index++] = GLX_DOUBLEBUFFER; + glxAttrs[index++] = True; + glxAttrs[index] = None; + + fbConfigList = find_AA_S_FBConfigs(display, screen, + glxAttrs, sVal, + antialiasVal, index); + + if(fbConfigList != NULL) { + return fbConfigList; + } + } + + if (dbVal == UNNECESSARY || dbVal== PREFERRED) { + index = dbIndex; + glxAttrs[index++] = GLX_DOUBLEBUFFER; + glxAttrs[index++] = False; + glxAttrs[index] = None; + + fbConfigList = find_AA_S_FBConfigs(display, screen, + glxAttrs, sVal, + antialiasVal, index); + + if(fbConfigList != NULL) { + return fbConfigList; + } + } + + if (dbVal == UNNECESSARY) { + index = dbIndex; + glxAttrs[index++] = GLX_DOUBLEBUFFER; + glxAttrs[index++] = True; + glxAttrs[index] = None; + + fbConfigList = find_AA_S_FBConfigs(display, screen, + glxAttrs, sVal, + antialiasVal, index); + + if(fbConfigList != NULL) { + return fbConfigList; + } } - return vis_info; + + return NULL; } /* - * Uses the past in array to choose the best OpenGL visual. + * Uses the passed in array to choose the best OpenGL visual. * When the "best" visual cannot be used, the "enums" (three * state attributes) are looped through setting/resetting in all * combinations in hopes of finding an valid visual. @@ -193,34 +252,47 @@ jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_chooseOglVisual( jlong display, jint screen, jintArray attrList, - jlongArray vInfArray) + jlongArray fbConfigArray) { - VisualID vis_id = 0; jint *mx_ptr; - int glxAttrs[256]; /* value, attr pair plus a None */ + int glxAttrs[MAX_GLX_ATTRS_LENGTH]; /* value, attr pair plus a None */ int index; - XVisualInfo *vis_info = NULL; + GLXFBConfig *fbConfigList = NULL; /* use to cycle through when attr is not REQUIRED */ int sVal; - int sIndex; + int dbVal; + int antialiasVal; - int dbVal; - int dbIndex; + int drawableIndex; - int antialiasVal; - int antialiasIndex; + jlong *fbConfigListPtr = NULL; + int status, major, minor; - const char *glxExtensions = NULL; - jlong *visInfo = (*env)->GetLongArrayElements(env, vInfArray, NULL); + Display *dpy = (Display *) display; + fbConfigListPtr = (*env)->GetLongArrayElements(env, fbConfigArray, NULL); mx_ptr = (jint *)(*env)->GetPrimitiveArrayCritical(env, attrList, NULL); /* * convert Java 3D values to GLX */ index = 0; - glxAttrs[index++] = GLX_RGBA; /* only interested in RGB visuals */ + + /* Specify pbuffer as default */ + /* Fix for Issue 20 */ + glxAttrs[index++] = GLX_DRAWABLE_TYPE; + drawableIndex = index; + glxAttrs[index++] = (GLX_PBUFFER_BIT | GLX_WINDOW_BIT); + + /* only interested in RGBA type */ + glxAttrs[index++] = GLX_RENDER_TYPE; + glxAttrs[index++] = GLX_RGBA_BIT; + + /* only interested in FBConfig with associated X Visual type */ + glxAttrs[index++] = GLX_X_RENDERABLE; + glxAttrs[index++] = True; + glxAttrs[index++] = GLX_RED_SIZE; glxAttrs[index++] = mx_ptr[RED_SIZE]; glxAttrs[index++] = GLX_GREEN_SIZE; @@ -229,107 +301,81 @@ jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_chooseOglVisual( glxAttrs[index++] = mx_ptr[BLUE_SIZE]; glxAttrs[index++] = GLX_DEPTH_SIZE; glxAttrs[index++] = mx_ptr[DEPTH_SIZE]; - + glxAttrs[index] = None; - dbIndex = index++; dbVal = mx_ptr[DOUBLEBUFFER]; - - sIndex = index++; sVal = mx_ptr[STEREO]; - - antialiasIndex = index++; antialiasVal = mx_ptr[ANTIALIASING]; - /* glxAttrs[index] = None; */ (*env)->ReleasePrimitiveArrayCritical(env, attrList, mx_ptr, 0); + fbConfigList = find_DB_AA_S_FBConfigs(display, screen, glxAttrs, sVal, + dbVal, antialiasVal, index); - if(antialiasVal == REQUIRED || antialiasVal== PREFERRED) { - /* try GLX_ARB_multisample */ - glxExtensions = (const char *)glXGetClientString((Display*)display, GLX_EXTENSIONS); - + if(fbConfigList == NULL) { // Try with Pixmap, if Pbuffer fail. */ + + glxAttrs[drawableIndex] = (GLX_PIXMAP_BIT | GLX_WINDOW_BIT); + + fbConfigList = find_DB_AA_S_FBConfigs(display, screen, glxAttrs, sVal, + dbVal, antialiasVal, index); - if(isExtensionSupported(glxExtensions, "GLX_ARB_multisample")){ - /* path 1: */ - /* Query the visual with mulitsamples */ - - index = antialiasIndex; - glxAttrs[index++] = GLX_SAMPLE_BUFFERS_ARB; - glxAttrs[index++] = 1; - glxAttrs[index++] = GLX_SAMPLES_ARB; - glxAttrs[index++] = 1; - glxAttrs[index++] = None; - vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex, - dbVal, dbIndex); - - if(vis_info != NULL) { - vis_id = XVisualIDFromVisual(vis_info->visual); - visInfo[0] = (jlong)vis_info; - (*env)->ReleaseLongArrayElements(env, vInfArray, visInfo, 0); - return vis_id; - } - } } - - /* normal path */ - if ( antialiasVal == REQUIRED || antialiasVal == PREFERRED) { - /* step 1 : enable antialiasing */ - index = antialiasIndex; - glxAttrs[index++] = GLX_ACCUM_RED_SIZE; - glxAttrs[index++] = 8; - glxAttrs[index++] = GLX_ACCUM_GREEN_SIZE; - glxAttrs[index++] = 8; - glxAttrs[index++] = GLX_ACCUM_BLUE_SIZE; - glxAttrs[index++] = 8; - glxAttrs[index++] = None; - vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex, - dbVal, dbIndex); + + if(fbConfigList == NULL) { // Try with Window only, if Pixmap fail. + glxAttrs[drawableIndex] = GLX_WINDOW_BIT; + + fbConfigList = find_DB_AA_S_FBConfigs(display, screen, glxAttrs, sVal, + dbVal, antialiasVal, index); - if( vis_info == NULL) { - /* try disable antialiasing if it is PREFERRED */ - if(antialiasVal == PREFERRED) { - glxAttrs[antialiasIndex] = None; - vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex, - dbVal, dbIndex); - } - } - - visInfo[0] = (jlong)vis_info; - (*env)->ReleaseLongArrayElements(env, vInfArray, visInfo, 0); - - if( vis_info != NULL) { - vis_id = XVisualIDFromVisual(vis_info->visual); - return vis_id; - } else { - return 0; - } } + fbConfigListPtr[0] = (jlong)fbConfigList; + (*env)->ReleaseLongArrayElements(env, fbConfigArray, fbConfigListPtr, 0); + + /* For debug only. + if(fbConfigList != NULL) { + int val; + + glXGetFBConfigAttrib(dpy, fbConfigList[0], + GLX_FBCONFIG_ID, &val); + + fprintf(stderr, "display 0x%x, fbConfigList 0x%x, fbConfig 0x%x, fbConfigId %d\n", + (int) display, (int) fbConfigList, (int) fbConfigList[0], val); + + } + else { + fprintf(stderr, "display 0x%x, fbConfigList 0x%x\n", + (int) display, (int) fbConfigList); + } + */ - glxAttrs[antialiasIndex] = None; - vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex, - dbVal, dbIndex); - - visInfo[0] = (jlong)vis_info; - (*env)->ReleaseLongArrayElements(env, vInfArray, visInfo, 0); + if(fbConfigList != NULL) { + int vis_id; + + if(glXGetFBConfigAttrib(dpy, fbConfigList[0], GLX_VISUAL_ID, &vis_id) != Success) { + fprintf(stderr, "Java 3D ERROR: unable to get VisualID\n"); + return 0; + } - if( vis_info != NULL) { - vis_id = XVisualIDFromVisual(vis_info->visual); - return vis_id; + /* fprintf(stderr, "********* VisualID = %d\n", vis_id ); */ + + return (jint) vis_id; + } else { return 0; } -} +} JNIEXPORT -void JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_freeVisual( +void JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_freeFBConfig( JNIEnv *env, jclass class, /* this is a static native method */ - jlong visInfo) + jlong fbConfigListPtr) { - XFree((XVisualInfo *)visInfo); + GLXFBConfig *fbConfigList = (GLXFBConfig *) fbConfigListPtr; + XFree(fbConfigList); } diff --git a/src/native/ogl/NativeScreenInfo.c b/src/native/ogl/NativeScreenInfo.c index c92900c..23ad8b8 100644 --- a/src/native/ogl/NativeScreenInfo.c +++ b/src/native/ogl/NativeScreenInfo.c @@ -32,6 +32,10 @@ #endif #if defined(SOLARIS) || defined(__linux__) + +#pragma weak glXChooseFBConfig + + /* * Class: javax_media_j3d_NativeScreenInfo * Method: openDisplay @@ -40,14 +44,13 @@ JNIEXPORT jlong JNICALL Java_javax_media_j3d_NativeScreenInfo_openDisplay( JNIEnv *env, - jobject obj) + jclass cls) { Display* dpy; dpy = XOpenDisplay(NULL); return (jlong)dpy; } - /* * Class: javax_media_j3d_NativeScreenInfo * Method: getDefaultScreen @@ -56,10 +59,70 @@ Java_javax_media_j3d_NativeScreenInfo_openDisplay( JNIEXPORT jint JNICALL Java_javax_media_j3d_NativeScreenInfo_getDefaultScreen( JNIEnv *env, - jobject obj, + jclass cls, jlong display) { Display* dpy = (Display*)display; return (jint)DefaultScreen(dpy); } + +/* + * Class: javax_media_j3d_NativeScreenInfo + * Method: queryGLX13 + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_javax_media_j3d_NativeScreenInfo_queryGLX13( + JNIEnv *env, + jclass cls, + jlong display) +{ + /* Fix for Issue 20 */ + void (*tmpfp)(); + int major, minor; + int errorBase, eventBase; + Display* dpy = (Display*)display; + // It should be cleaner to return both the major and minor to the caller. + + if (!glXQueryExtension(dpy, &errorBase, &eventBase)) { + fprintf(stderr, "Java 3D ERROR : GLX extension is not supported\n"); + fprintf(stderr, " GLX version 1.3 or higher is required\n"); + return JNI_FALSE; + } + +#if 0 /* Temporary disable this code segment because the ATI driver incorrectly + return 1.2 */ + + /* Check for glX 1.3 and higher */ + if (glXQueryVersion(dpy, &major, &minor)) { + /* fprintf(stderr, "Checking glX version : %d.%d\n",major, minor); */ + if (!(major == 1 && minor >= 3)) { + fprintf(stderr, "Java 3D ERROR : GLX version = %d.%d\n", major, minor); + fprintf(stderr, " GLX version 1.3 or higher is required\n"); + return JNI_FALSE; + } + } + else { + fprintf(stderr, "Java 3D ERROR : Unable to query GLX version\n"); + fprintf(stderr, " GLX version 1.3 or higher is required\n"); + return JNI_FALSE; + } + +#elseif + + tmpfp = (void (*)())glXChooseFBConfig; + + if (tmpfp == NULL) { + glXQueryVersion(dpy, &major, &minor); + fprintf(stderr, "Java 3D ERROR : glXChooseFBConfig not found\n"); + fprintf(stderr, " GLX version = %d.%d\n", major, minor); + fprintf(stderr, " GLX version 1.3 or higher is required\n"); + return JNI_FALSE; + } + +#endif + + return JNI_TRUE; +} + #endif |