JOGL GLContext Threading

Sorry if this is a Noobie question
I have a question regarding GLContext and Threading. I have an application which given a data set, it decodes it , then renders it and outputs a png file. The whole application is threaded so that it can process multiple files at once. I have been working to migrate to jogl to speed up the rendering. I am using pbuffers and I have a created a demo program which just does the rendering and output for a sinlge pbuffer without threading. The demo program creates a pbuffer, draws a triangle and then outputs an image using the new ScreenShot class and ImageIO. This works without a problem. But when I implement it into my multithreaded application I get problems associated with GLContext from the ScreenShot class. I get a null pointer exception in the ScreenShot classon the line GLU.getCurrentGL(); within readToBufferedImage

Is it possible to have multiple threads each with their own PBuffer for drawing and output?
I can provide code if needed.
Thanks
jason

Can you please provide the stack trace and the surrounding code? I would have thought that GLU.getCurrentGL() should throw GLException, not NullPointerException.

Regardless, it sounds to me like you forgot to make your pbuffer’s OpenGL context current. Look at the source code for demos.texture.TextureConvert in the jogl-demos workspace for how to properly use a pbuffer in a single thread’s context.

Thanks for your response and you are correct it throws a GLException, I had changed it around a few ways and tried several things and I lost site of the root Exception being thrown. Here is the surrounding code

Here is where I create the pbuffer and make it’s context current

 GLCapabilities cCaps = new GLCapabilities();
        cCaps.setHardwareAccelerated(false);
        cCaps.setDoubleBuffered(false);
        cCaps.setRedBits(8); // 32 bit color resolution
        cCaps.setBlueBits(8);
        cCaps.setGreenBits(8);
        cCaps.setAlphaBits(8);
        
        pbuffer = GLDrawableFactory.getFactory().createGLPbuffer(cCaps, null, dim.width,dim.height, null);
       
       System.out.println("Current "+GLContext.getCurrent());
       pbuffer.getContext().makeCurrent();

Here is where I call the Screenshot from the display method.


System.out.println("Writing graphics");
          Screenshot.readToBufferedImage(dim.width,dim.height);

Here is the stack trace

Writing graphics
Exception in thread "0 Chain .54 Nmi Base Reflectivity" javax.media.opengl.GLException: No OpenGL context current on this thread
        at javax.media.opengl.glu.GLU.getCurrentGL(GLU.java:232)
        at com.sun.opengl.utils.Screenshot.readToBufferedImage(Screenshot.java:128)
        at Renderers.OpenGLRadialRenderer_P.display(OpenGLRadialRenderer_P.java:141)
        at Renderers.OpenGLRadialRenderer_P.getDataEvent(OpenGLRadialRenderer_P.java:82)
        at RadarDecoders.RadarDecoder.fireRenderEvent(RadarDecoder.java:79)
        at RadarDecoders.FourBitRadialDecoder.readRows(FourBitRadialDecoder.java:80)
        at RadarDecoders.FourBitRadialDecoder.beginDecoding(FourBitRadialDecoder.java:31)
        at Chains.DecoderChain.startNextProcess(DecoderChain.java:122)
        at Chains.DecoderChain.run(DecoderChain.java:154)

Like I said this is all done within a Thread that has this renderer in it. The renderer gets the data and does the drawing and when it finishes in the display method it then trys to get a BufferedImage using Screenshot. And that is where the GLException gets thrown.

Thanks
jason

Without seeing more of the code it’s impossible to see where the error is. The GLException’s error message is correct; somewhere along the line you have not made the pbuffer’s GLContext current on the current thread. I don’t know if you’re using the GLEventListener mechanism but if you are then you need to call GLPbuffer.display(), not GLEventListener.display(). Please look at the demos.texture.TextureConvert demo, which uses pbuffers in a very similar way.

Ken,
Thanks for your help. I fixed the problem this morning after reading your post. I have the pbuffer creation in the constructor for the class that implements the GLEventListener. Once I get all of the data I call pbuffer.display(), and in the display method for the GLEventListener I draw the image and I finish by calling the ScreenShot.

I was calling pbuffer.getContext().makeCurrent() in the constructor.
So when you call pbuffer.display() does that make the context current?

Again thanks for your help. Now I just have to optimize my code.
Jason

Awaiting observer status. Then I will submit it.
Jason

That makes the context current right now on the current thread, but it sounds like there was a long period of time between when you made the context current and when the screenshot was taken. You should avoid that especially in the face of multithreading.