Well, hello again JOGL community. I'm trying to make a little test case working, and I'm a bit stumped.
Rapidly, the test tries to list all availiable graphic card extensions using a AWT rendering context. It's actually a very, very stripped down test case in a much larger project, but on it's own it's quite informative and while it looks simple, I'm getting a NPE (NullPointerException) in the GLCanvas class. I figure it's not supposed to happen, but I'm also curious to know if there is a better way to quickly and dirtily get the extensions list. Here is the unit test code: ******* import java.util.Collections; import java.util.SortedSet; import java.util.TreeSet; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GL; import javax.media.opengl.GL2; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLPbuffer; import javax.media.opengl.GLProfile; import javax.media.opengl.awt.GLCanvas; public class testJOGL2 { public static void main(String[] args) { GLProfile.initSingleton(true); GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2)); GLCanvas glc = new GLCanvas(caps); GLDrawableFactory usine = glc.getFactory(); GLCapabilitiesImmutable glci = glc.getChosenGLCapabilities(); GLCapabilitiesChooser glcc = new DefaultGLCapabilitiesChooser(); AbstractGraphicsDevice agd = usine.getDefaultDevice(); GLPbuffer pbuffer = usine.createGLPbuffer(agd, glci, glcc, 256, 256, null); GLContext context = pbuffer.getContext(); context.makeCurrent(); GL2 gl = pbuffer.getContext().getGL().getGL2(); String extensions = gl.glGetString(GL.GL_EXTENSIONS); String[] tabExtensions = extensions.split(" "); SortedSet<String> setExtensions = new TreeSet<String>(); Collections.addAll(setExtensions, tabExtensions); System.out.println(setExtensions); } } ********* Here is the console output: Info: XInitThreads() called for concurrent Thread support Exception in thread "main" java.lang.NullPointerException at javax.media.opengl.awt.GLCanvas.getFactory(GLCanvas.java:694) at testJOGL2.main(testJOGL2.java:24) On a related note: is the first line some kind of common-loggings ou Log4J log output? How can I get rid of it? |
Administrator
|
You might try looking at https://github.com/sgothel/jogl/blob/master/src/jogl/classes/com/jogamp/opengl/JoglVersion.java. It shows how the etc/test.sh file prints out the extensions information.
The "Info: XInitThreads() called for concurrent Thread support" message doesn't seem to occur in the JOGL code anywhere, so it must be coming from inside the XInitThreads call. I'm not sure how to shut it off. |
What I would want to know is if this situation is a bug in the JOGL GLDrawable class or just a bad manipulation on my part. Since I only use JOGL classes the create that NPE I have strong incentives to label it a bug.
If it's a bug I'll file the bug report ASAP. If it's not then I'll look for another way. |
thanks, michael On 01/18/2011 08:29 PM, François Coupal [via jogamp] wrote: What I would want to know is if this situation is a bug in the JOGL GLDrawable class or just a bad manipulation on my part. Since I only use JOGL classes the create that NPE I have strong incentives to label it a bug. -- http://michael-bien.com/ |
Thx, I'll file the bug report. If I encounter antother one in the future I'll file it on the spot.
|
Administrator
|
In reply to this post by François Coupal
When I run your code on CentOS 64-bit, I get a different exception that you do:
Info: XInitThreads() called for concurrent Thread support Exception in thread "main" javax.media.opengl.GLException: No AWTGraphicsConfiguration: AWT-GLCanvas[ null, null-drawable] at javax.media.opengl.awt.GLCanvas.getChosenGLCapabilities(GLCanvas.java:693) at name.wadewalker.onetriangle.CapsCheck.main(CapsCheck.java:26) This is because the awtConfig member in the GLCanvas isn't set up until you add it to a frame and set it visible. |
Administrator
|
In reply to this post by François Coupal
Note there's a problem with our Bugzilla login -- workaround is explained at https://jogamp.org/wiki/index.php/Contributing_a_new_feature_or_fix#Create_an_enhancement_request_or_bug_report. This page also explains how to contribute a unit test for your bug report.
Also, please include the info requested at https://jogamp.org/wiki/index.php/Jogl_FAQ#Bugreports_.26_Testing. Thanks for your help! |
Thanks for the heads-up. I gathered the missing information and added it to the bug report. Here is the bug link: https://jogamp.org/bugzilla/show_bug.cgi?id=460
The idea behind all this is to get the extensions as fast as I can, and if possible without having to set-up too much. I use a GLCanvas mainly because it's the main GLDrawable my main project use. For this I heard the best way is to use a pbuffer, but acquiring that bpuffer ain't trivial, to say the least. At that point I'm not even trying to render anything, just to get some vital info on the video card and run some tests on off-screen rendering (like testing FBOs multisampling for example). These more advanced tests could be done afterwards, and thus are not in the small code snippet above. Ideally, I'd like to dynamically set up my render engine based on the capabilities of the graphic card. Depending on which extensions are availiable, many effects won't work, or better effects can be atempted if some very specific extension are availiable. This information is best gotten as soon as possible. And in my engine, that's even before my main rendering frame has been set up. |
Administrator
|
The library definitely shouldn't throw an NPE, so this bug is certainly legitimate, but the info you want may not be accessible without creating a window, at least with GL2 (info here: http://www.opengl.org/wiki/Creating_an_OpenGL_Context). It sounds like the ability to create a GL context without a window didn't show up until GL3. I don't have direct experience with this however, so one of the other guys may know different.
|
It would appear the bug report (460) has been closed with a fix.
However I can't make it work even with recent builds (such as RC2 and build 341). The only post contains "SCM refs", which I have no idea how they are supposed to help me. Or am I missing something? I will try to use an alternate strategy to try to fetch basic OpenGL info, such as creating a unused AWT windows to jump-start a correct OpenGL context, then extracting info from it. Basically, what I am trying to do is EXACTLY what the quick info application does, but with an AWT library instead of a NEWT one. I just can't get anything to work without NPEs being thrown all over the place. Link to the quick app: http://jogamp.org/deployment/webstart/application-version.jnlp |
Found a workaround fooling around with Wade Walker's AWT examples on the JogAmp wiki.
It appears that even though the canvas is created, it will not be able to process the default capabilities until a Frame has been created AND shown using the "setVisible(true)" method. Trying to access them will throw an NPE. From that moment, it is possible to fetch default capabilities and create a PBuffer for graphic card verifications. Tried it with both the default profile (whatever it may be) and a GL2 profile. I will try to use a NEWT-Based window toolkit to access a window-less PBuffer. If I can't then it would mean there are no way JOGL can fetch capabilities without the help of a window toolkit. I'd very much like to be proven wrong on this. By the way, I've found that using the method "GLProfile.initSingleton(false);" in Eclipse causes the windows to be unresponsive to closing. I have to switch them to "true" to be able to close them using the window close button. It's the exact opposite behavior that is mentionned in the comment just above the code line in the basic examples. |
Administrator
|
On Friday, March 04, 2011 23:32:43 François Coupal [via jogamp] wrote:
> > Found a workaround fooling around with Wade Walker's AWT examples on the > JogAmp wiki. > > It appears that even though the canvas is created, it will not be able to > process the default capabilities until a Frame has been created AND shown > using the "setVisible(true)" method. Trying to access them will throw an > NPE. Please post this NPE using the current RC2 - thx. http://jogamp.org/deployment/archive/rc/v2.0-rc2/archive/ http://jogamp.org/deployment/archive/rc/v2.0-rc2/all.artifact.properties.sorted http://jogamp.org/git/?p=jogl.git;a=commit;h=bcf5d6ac871a29398b441df617923d3dd2cf35c1 Even though it's true, that only after GLCanvas addNotify/display a valid context/drawable/etc is instantiated, we shall not NPE. I would like to fix it. > > >From that moment, it is possible to fetch default capabilities and create a > PBuffer for graphic card verifications. Tried it with both the default > profile (whatever it may be) and a GL2 profile. > > I will try to use a NEWT-Based window toolkit to access a window-less > PBuffer. If I can't then it would mean there are no way JOGL can fetch > capabilities without the help of a window toolkit. I'd very much like to be > proven wrong on this. The only requirement here is that the shared resources for the target device have been initialized. In short: 'GLProfile.initSingleton(false);' shall be passed. http://jogamp.org/git/?p=jogl.git;a=blob;f=src/newt/classes/jogamp/newt/awt/opengl/VersionApplet.java;h=18524d0bac330afbd04a425720d548170da84de7;hb=HEAD#l103 // shortcut: GLProfile.initSingleton(false); List/*<GLCapabilitiesImmutable>*/ availCaps = GLDrawableFactory.getDesktopFactory().getAvailableCapabilities(null); And in action: http://jogamp.org/deployment/webstart/applet-version-jnlp.html The fact that the applet also uses a GLCanvas is only due to the fact, that it dumps it's actual GLContext as well. http://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/javax/media/opengl/GLDrawableFactory.html#getAvailableCapabilities%28javax.media.nativewindow.AbstractGraphicsDevice%29 > > By the way, I've found that using the method > "GLProfile.initSingleton(false);" in Eclipse causes the windows to be > unresponsive to closing. I have to switch them to "true" to be able to close > them using the window close button. It's the exact opposite behavior that is > mentionned in the comment just above the code line in the basic examples. interesting. I guess we have to discuss the whole SWT 'behavior' much more in detail. Good that we have Wade helping here. ~Sven |
Administrator
|
In reply to this post by François Coupal
I have seen this too. It varies by platform, sometimes you have to set it true, other times false to get the right result. I'm going to add some more unit tests to try these things out, once I get on top of some other issues. |
Administrator
|
Wade, does this problem happen only when you mix SWT Canvas with JOGL 2 or when you use SWT_AWT too?
Julien Gouesse | Personal blog | Website
|
Administrator
|
I haven't tested it very systematically yet, I've just noticed that some builds have the problem.
|
Warning, long post because of code snippets and error messages
Here is a JUnit test case for recreating the NPE problem. As you can see, it does not even try to use a Frame even though it uses a GLCanvas (In the following post I will put up some code that will). It breaks at the seventh line in the main method. An NPE is thrown. This code breaks using the RC2 and build 341 JOGL libraries (on Ubuntu Linux). Following is the error messages when executed (with build 341) as an application, not as a unit test. ************* import java.util.Collections; import java.util.SortedSet; import java.util.TreeSet; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GL; import javax.media.opengl.GL2; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLPbuffer; import javax.media.opengl.GLProfile; import javax.media.opengl.awt.GLCanvas; import org.junit.Test; public class testJOGL2 { public static void main(String[] args) { testJOGL2 instance = new testJOGL2(); instance.testJogl2ExtensionCheck(); } @Test public void testJogl2ExtensionCheck() { GLProfile.initSingleton(false); // GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2)); GLCapabilities caps = new GLCapabilities(GLProfile.getDefault()); GLCanvas glc = new GLCanvas(caps); GLDrawableFactory usine = glc.getFactory(); GLCapabilitiesImmutable glci = glc.getChosenGLCapabilities(); GLCapabilitiesChooser glcc = new DefaultGLCapabilitiesChooser(); AbstractGraphicsDevice agd = usine.getDefaultDevice(); GLPbuffer pbuffer = usine.createGLPbuffer(agd, glci, glcc, 256, 256, null); GLContext context = pbuffer.getContext(); context.makeCurrent(); GL2 gl = pbuffer.getContext().getGL().getGL2(); String extensions = gl.glGetString(GL.GL_EXTENSIONS); String[] tabExtensions = extensions.split(" "); SortedSet<String> setExtensions = new TreeSet<String>(); Collections.addAll(setExtensions, tabExtensions); System.out.println(setExtensions); } } ************************ java.lang.Throwable: main - Info: NativeWindowFactory.<init> at javax.media.nativewindow.NativeWindowFactory.<clinit>(NativeWindowFactory.java:119) at javax.media.opengl.GLProfile.initProfilesForDefaultDevices(GLProfile.java:1164) at javax.media.opengl.GLProfile.access$000(GLProfile.java:71) at javax.media.opengl.GLProfile$1.run(GLProfile.java:117) at java.security.AccessController.doPrivileged(Native Method) at javax.media.opengl.GLProfile.initSingleton(GLProfile.java:115) at testJOGL2.testJogl2ExtensionCheck(testJOGL2.java:29) at testJOGL2.main(testJOGL2.java:24) main - NativeWindowFactory.initSingleton(false) Info: XInitThreads() called for concurrent Thread support NativeWindowFactory.registerFactory() interface javax.media.nativewindow.NativeWindow -> jogamp.nativewindow.NativeWindowFactoryImpl@1e859c0 NativeWindowFactory firstUIActionOnProcess false NativeWindowFactory isAWTAvailable false, defaultFactory jogamp.nativewindow.NativeWindowFactoryImpl@1e859c0 X11Util.isFirstX11ActionOnProcess: false GraphicsConfigurationFactory.registerFactory() class javax.media.nativewindow.x11.X11GraphicsDevice -> jogamp.nativewindow.x11.X11GraphicsConfigurationFactory@1415de6 GraphicsConfigurationFactory.registerFactory() interface javax.media.nativewindow.AbstractGraphicsDevice -> jogamp.nativewindow.DefaultGraphicsConfigurationFactoryImpl@121cc40 GraphicsConfigurationFactory.registerFactory() class javax.media.nativewindow.x11.X11GraphicsDevice -> jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory@1386000 X11 Display(NULL) <:0.0> GraphicsConfigurationFactory.registerFactory() class javax.media.nativewindow.egl.EGLGraphicsDevice -> jogamp.opengl.egl.EGLGraphicsConfigurationFactory@c5c3ac java.lang.Exception: X11Util.Display: Created new NamedX11Display[:0.0, 0x918ead8, refCount 1, unCloseable false]. Thread main-SharedResourceRunner at jogamp.nativewindow.x11.X11Util.createDisplay(X11Util.java:317) at jogamp.opengl.x11.glx.X11GLXDrawableFactory$SharedResourceImplementation.createSharedResource(X11GLXDrawableFactory.java:174) at jogamp.opengl.SharedResourceRunner.run(SharedResourceRunner.java:206) at java.lang.Thread.run(Thread.java:619) main-SharedResourceRunner - X11GraphicsDevice.setCloseDisplay(true): X11GraphicsDevice[type X11, connection :0.0, unitID 0, handle 0x918ead8] chooseCapabilities: Using recommendedIndex: idx 0 Exception in thread "main" java.lang.NullPointerException at javax.media.opengl.awt.GLCanvas.toString(GLCanvas.java:748) at java.lang.String.valueOf(String.java:2826) at java.lang.StringBuilder.append(StringBuilder.java:115) at javax.media.opengl.awt.GLCanvas.getChosenGLCapabilities(GLCanvas.java:705) at testJOGL2.testJogl2ExtensionCheck(testJOGL2.java:34) at testJOGL2.main(testJOGL2.java:24) main-SharedResourceRunner - X11GraphicsDevice.close(): X11GraphicsDevice[type X11, connection :0.0, unitID 0, handle 0x918ead8] java.lang.Exception: X11Util.Display: Closing new NamedX11Display[:0.0, 0x918ead8, refCount 1, unCloseable false]. Thread main-SharedResourceRunner at jogamp.nativewindow.x11.X11Util.closeDisplay(X11Util.java:342) at javax.media.nativewindow.x11.X11GraphicsDevice.close(X11GraphicsDevice.java:96) at jogamp.opengl.x11.glx.X11GLXDrawableFactory$SharedResourceImplementation.releaseSharedResource(X11GLXDrawableFactory.java:246) at jogamp.opengl.SharedResourceRunner.releaseSharedResources(SharedResourceRunner.java:245) at jogamp.opengl.SharedResourceRunner.run(SharedResourceRunner.java:229) at java.lang.Thread.run(Thread.java:619) java.lang.Exception: X11Util.Display: Shutdown (close open / pending Displays: false, open (no close attempt): 0/0, open (no close attempt and uncloseable): 0) at jogamp.nativewindow.x11.X11Util.shutdown(X11Util.java:198) at jogamp.opengl.x11.glx.X11GLXDrawableFactory.shutdownInstance(X11GLXDrawableFactory.java:320) at javax.media.opengl.GLDrawableFactory.shutdownImpl(GLDrawableFactory.java:201) at javax.media.opengl.GLDrawableFactory.access$100(GLDrawableFactory.java:91) at javax.media.opengl.GLDrawableFactory$2.run(GLDrawableFactory.java:172) at java.lang.Thread.run(Thread.java:619) ********************* |
Now, a working implementation that uses Wade examples. To make it work you need the "OneTriangle" class that is shown in the examples in the wiki.
A you will see, you can "play around" with it to make it crash or make it work just by commenting certains lines, such as "frame.setVisible(true)" (line 72). If this line is missing, an NPE will be thrown. (NPE thown because of a faulty toString method, same as the post above) Also notice the "GLProfile.initSingleton( true );" (line 31) in the static method. As discussed above, you mileage may vary depending on unknown circumstances. ************************************** import java.awt.Frame; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Collections; import java.util.SortedSet; import java.util.TreeSet; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GL; import javax.media.opengl.GL2; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLEventListener; import javax.media.opengl.GLPbuffer; import javax.media.opengl.GLProfile; import javax.media.opengl.awt.GLCanvas; /** * A minimal program that draws with JOGL in an AWT Frame. * * @author Wade Walker */ public class OneTriangleAWT { static { GLProfile.initSingleton( true ); } public static void main( String [] args ) { // GLProfile glprofile = GLProfile.getDefault(); GLProfile glprofile = GLProfile.get(GLProfile.GL2); GLCapabilities glcapabilities = new GLCapabilities( glprofile ); final GLCanvas glcanvas = new GLCanvas( glcapabilities ); glcanvas.addGLEventListener( new GLEventListener() { @Override public void reshape( GLAutoDrawable glautodrawable, int x, int y, int width, int height ) { OneTriangle.setup( glautodrawable.getGL().getGL2(), width, height ); } @Override public void init( GLAutoDrawable glautodrawable ) { } @Override public void dispose( GLAutoDrawable glautodrawable ) { } @Override public void display( GLAutoDrawable glautodrawable ) { OneTriangle.render( glautodrawable.getGL().getGL2(), glautodrawable.getWidth(), glautodrawable.getHeight() ); } }); final Frame frame = new Frame( "One Triangle AWT" ); frame.add( glcanvas ); frame.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent windowevent ) { frame.remove( glcanvas ); frame.dispose(); System.exit( 0 ); } }); frame.setSize( 640, 480 ); frame.setVisible( true ); GLDrawableFactory usine = glcanvas.getFactory(); GLCapabilitiesImmutable glci = glcanvas.getChosenGLCapabilities(); GLCapabilitiesChooser glcc = new DefaultGLCapabilitiesChooser(); AbstractGraphicsDevice agd = usine.getDefaultDevice(); GLPbuffer pbuffer = usine.createGLPbuffer(agd, glci, glcc, 256, 256, null); GLContext context = pbuffer.getContext(); context.makeCurrent(); GL2 gl = pbuffer.getContext().getGL().getGL2(); String extensions = gl.glGetString(GL.GL_EXTENSIONS); String[] tabExtensions = extensions.split(" "); SortedSet<String> setExtensions = new TreeSet<String>(); Collections.addAll(setExtensions, tabExtensions); System.out.println(setExtensions); } } |
Sven, I will post these code snippets in the 460 bug, probably re-opening it.
I just thought that posting the code snippet here so people may play a bit with them. Easier than searching in the bugzilla database. In the meantime, I'll use the code you sent me to experiment with various NEWT components. |
I fiddled around the source code for the VersionApplet program, with Sven direction about the source code
> The only requirement here is that the shared resources for the target device > have been initialized. > In short: 'GLProfile.initSingleton(false);' shall be passed. > > http://jogamp.org/git/?p=jogl.git;a=blob;f=src/newt/classes/jogamp/newt/awt/opengl/VersionApplet.java;h=18524d0bac330afbd04a425720d548170da84de7;hb=HEAD#l103 > > // shortcut: > GLProfile.initSingleton(false); > List/*<GLCapabilitiesImmutable>*/ availCaps = GLDrawableFactory.getDesktopFactory().getAvailableCapabilities(null); I tested this, and this is not the info I am looking for, although it does work. The content of such a list are like this: GLCaps[0x21 0x75: on-scr, rgba 8/8/8/0, opaque, accum-rgba 16/16/16/16, dp/st/ms: 24/8/0, dbl, mono , hw, GLProfile[GL2/GL2]] GLCaps[0x21 0x75: offscr, rgba 8/8/8/0, opaque, accum-rgba 16/16/16/16, dp/st/ms: 24/8/0, dbl, mono , hw, GLProfile[GL2/GL2], pbuffer [r2t 0, r2tr 0, float 0]] What I need to get are the extension list. That list is availiable later in the code in the "init()" method of a GlCanvas, hence after it has been made visible by a frame of some kind. the code line is this: JoglVersion.getGLInfo(gl, null).toString(); The problem is that it needs a GL object, and the associated context. If I try to access that info before the windows made visible I'm back into the NPE which are the scope of this thread. |
Administrator
|
On Monday, March 07, 2011 12:36:53 François Coupal [via jogamp] wrote:
> > I fiddled around the source code for the VersionApplet program, with Sven > direction about the source code > > > The only requirement here is that the shared resources for the target > > device > > have been initialized. > > In short: 'GLProfile.initSingleton(false);' shall be passed. > > > > http://jogamp.org/git/?p=jogl.git;a=blob;f=src/newt/classes/jogamp/newt/awt/opengl/VersionApplet.java;h=18524d0bac330afbd04a425720d548170da84de7;hb=HEAD#l103 > > > > // shortcut: > > GLProfile.initSingleton(false); > > List/**/ availCaps = > > GLDrawableFactory.getDesktopFactory().getAvailableCapabilities(null); > > I tested this, and this is not the info I am looking for, although it does > work. The content of such a list are like this: > > GLCaps[0x21 0x75: on-scr, rgba 8/8/8/0, opaque, accum-rgba 16/16/16/16, > dp/st/ms: 24/8/0, dbl, mono , hw, GLProfile[GL2/GL2]] > GLCaps[0x21 0x75: offscr, rgba 8/8/8/0, opaque, accum-rgba 16/16/16/16, > dp/st/ms: 24/8/0, dbl, mono , hw, GLProfile[GL2/GL2], pbuffer [r2t 0, r2tr > 0, float 0]] > > What I need to get are the extension list. That list is availiable later in > the code in the "init()" method of a GlCanvas, hence after it has been made > visible by a frame of some kind. the code line is this: > > JoglVersion.getGLInfo(gl, null).toString(); > Ok .. so not the GLCaps .. fine. > The problem is that it needs a GL object, and the associated context. If I > try to access that info before the windows made visible I'm back into the > NPE which are the scope of this thread. Orthogonal problems. Thank you for #460, please reopen it if not done yet, I will have a look at it next week. (Currently 'on tour' until next Wednesday). Assuming the bug is fixed, you can use an offscreen glcontext to query the extensions or the shared resources (we may like to have an public API for it). Cheers, Sven |
Free forum by Nabble | Edit this page |