"No OpenGL context current on this thread" - why?

I have a method that loads a texture called loadTexture().
The method just does this:

 textures = TextureIO.newTexture(new java.io.File("image.jpg"), false);

If I call that method from an actionListener (actionPerformed method) I get this error:

javax.media.opengl.GLException: No OpenGL context current on this thread

If I call loadTexture() from the init() methot, I don´t get the exception.

I want to load the texture by pressing a button, so why do I get that exception when trying to call the method from the action listener?

When you’re creating the texture, you need to be able to perform OpenGL operations. This is only allowed when there’s an OpenGL context ‘current’ on the calling thread. When you have your loadTexture() method invoked in the action listener, it’s not current because you haven’t made it so. When init() or display() are called, the GLCanvas makes sure that there is a context current for you, so the opengl work can happen.

I’d recommend creating a new TextureData object in your action listener, since all that does is load the file and prepare for transfer to the GPU without making opengl calls. Then in your display()/init() methods you check for any pending TextureData’s and convert them into new Textures (there should be a TextureIO.newTexture() that takes a TextureData object).

Thanks for answering!

I found a way to get around the problem. In the listener I put this line of code:

glContext.makeCurrent();

and then it worked.

Is that an ugly solution or is it OK to do in that way?

makeCurrent() could fail (You would have to check for this and maybe retry) or it might conflict with the display() callback (not sure about that). It will however work reasonable well as long as the OpenGL thread is the AWT Event Dispatcher Thread (EDT). This is the default for JOGL1 (don’t know about JOGL" but I guess it hasn’t changed), so you should be ok with your workaround…

If it works for you, that’s fine but IMO it’s an ugly solution. Also it’s letting you do too much work in the action listener. It’s generally recommended to not perform heavy operations (like loading/creating a texture) in an event handler because it blocks the EDT from responding to user input. The solution is somewhat complicated, so I’ll leave it off since it sounds like it’s not something you need to do right now.

It not only blocks the user input, it also blocks the display() call, since jogl does all it’s rendering work on the edt per default. So if you do heavy work in an action listener, you completely freeze your app for the time it takes to finish the operation.

I am making an application that lets the user import new images (that is creating new textures) during runtime so I do have to use some kind of event handler and create new textures in it.

Are there any good practices of how to code when letting a user import new images as textures during runtime?

For an explanation how to insert work into the display() call from outside, see http://www.java-gaming.org/index.php/topic,12475.msg99927.html#msg99927.

With this code you can do something like:


actionPerformed(ActionEvent evt)
{
	// put texture loading on a different thread, so the app stays responsive
	new Thread()
	{
		public void run()
		{
			// load the texturedata here
			final TextureData textureData = // (...)

			// use the texturedata from the display() callback
			GLQueue.getInstance().add( new GLAction()
			{
				public void execute(GL target)
				{
					Texture texture = TextureIO.newTexture(texturedata);
					// do whatever you need to do with the texture
					// (...)
				}
			});
		}

	}.start();
}

Looks complicated, but as soon as you understood the pattern you can make yourself some utility methods to hide this complexity.

Thanks! I understand the pattern and everything and I have got it working too but I get two uncheckd warnings (compiled with Xlint:unchecked) in the GLQueue class posted in this post http://www.java-gaming.org/index.php/topic,12475.msg99927.html#msg99927:

GLQueue.java:30: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.ArrayList



The warning refers to:

public void add(GLAction action) {
        synchronized (queue)  { queue.add(action);  }
}

And the line:

GLQueue.java:43: warning: [unchecked] unchecked call to ArrayList(java.util.Collection<? extends E>) as a member of the raw type java.util.ArrayList



The warning refers to:

temp = new ArrayList(queue);

Why do I get these warning?

Is it possible to correct them?

This is java 1.4 code so you get warnings for untyped collections in a 1.5+ jvm. Either ignore them or make the collections (ArrayLists) typed like


ArrayList<GLAction> temp = new ArrayList<GLAction>(queue);

You will have to type the queue list as well.

Hi,

I’m having a similar issue occurring with JOGL2. In JOGL1.1.1 you could call newTextureData without worrying GLContext to get a TextureData, and then in the GL display loop decide when to convert it to a Texture, or update a Texture, etc. Which I thought was the reason to have TextureData in the first place.

However in JOGL2 even trying to create a newTextureData will return this execption;


Exception in thread "main" javax.media.opengl.GLException: No OpenGL context current on this thread
        at javax.media.opengl.GLContext.getCurrentGL(GLContext.java:159)
        at com.sun.opengl.util.texture.awt.AWTTextureData.createFromImage(AWTTextureData.java:173)
        at com.sun.opengl.util.texture.awt.AWTTextureData.<init>(AWTTextureData.java:102)
        at com.sun.opengl.util.texture.spi.awt.IIOTextureProvider.newTextureData(IIOTextureProvider.java:69)
        at com.sun.opengl.util.texture.TextureIO.newTextureDataImpl(TextureIO.java:765)
        at com.sun.opengl.util.texture.TextureIO.newTextureData(TextureIO.java:180) 

Looking at the source code the single place where an openGL context is needed is in this if statement (inside of AWTTextureData.java):


 
GLProfile glp = GLContext.getCurrentGL().getGLProfile();
if (glp.isGL2()) { ... }


Anyhow, maybe I’m confused about this, but I thought the point in having the TextureData object was so that you could load in images/data without having an active context. And in JOGL2 you need to be in the GL thread to load the background data.

Maybe there is need for a constructor like:


AWTTextureData(int internalFormat, int pixelFormat, boolean mipmap, BufferedImage image, GLProfile profile) 

or


AWTTextureData(int internalFormat, int pixelFormat, boolean mipmap, BufferedImage image, String profileStr) 

?

-spiraljetty

You are right, the whole thing about TextureData was to separate texture preparation from the GL context. So I would consider this a bug.

Ok, glad you agree. What is the best way to file a bug report nowadays? It seems like the JOGL home on Project Kenai doesn’t have any issue tracking set up. -sj

already filed a bug :wink: :
https://kenai.com/bugzilla/show_bug.cgi?id=975

Ok thanks, I filed one on java.net as well. Is that site outdated now? It seems like it is still active.

https://jogl.dev.java.net/issues/show_bug.cgi?id=378

AFAIK it still serves as host for nightly builds but the new project home is kenai. (the repos etc on java.net are all outdated)

Hi, this TextureData bug hasn’t been fixed or addressed, as far as I can tell, despite being submitted to both the Project Kenai issue tracker and the older java.net issue tracker by myself and bienator over a month ago. To me it seems like a fairly important issue since it breaks the entire reason the TextureData classes were created in the first place.

Are most people still using jogl1, or are people forking jogl2 to fix bugs etc? Is using the Project Kenai issue tracker the best way to submit bugs? How come no one is using it and no one is responding to any of the bugs? Even if someone were to say “this bug is to trivial to address” it would be useful…

Thanks, sj