Roxxor
Senior Newbie 
|
 |
«
Posted
2009-08-09 15:56:10 » |
|
I have a method that loads a texture called loadTexture(). The method just does this: 1
| textures = TextureIO.newTexture(new java.io.File("image.jpg"), false); |
If I call that method from an actionListener (actionPerformed method) I get this error: 1
| 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?
|
|
|
|
|
lhkbob
|
 |
«
Reply #1 - Posted
2009-08-09 17:43:03 » |
|
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).
|
|
|
|
Roxxor
Senior Newbie 
|
 |
«
Reply #2 - Posted
2009-08-09 17:48:18 » |
|
Thanks for answering! I found a way to get around the problem. In the listener I put this line of code: 1
| glContext.makeCurrent(); |
and then it worked. Is that an ugly solution or is it OK to do in that way?
|
|
|
|
|
Games published by our own members! Check 'em out!
|
|
cylab
|
 |
«
Reply #3 - Posted
2009-08-09 18:13:03 » |
|
Thanks for answering! I found a way to get around the problem. In the listener I put this line of code: 1
| 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...
|
Mathias - I Know What [you] Did Last Summer!
|
|
|
lhkbob
|
 |
«
Reply #4 - Posted
2009-08-10 01:12:44 » |
|
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.
|
|
|
|
cylab
|
 |
«
Reply #5 - Posted
2009-08-10 10:24:37 » |
|
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.
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.
|
Mathias - I Know What [you] Did Last Summer!
|
|
|
Roxxor
Senior Newbie 
|
 |
«
Reply #6 - Posted
2009-08-10 13:01:36 » |
|
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?
|
|
|
|
|
cylab
|
 |
«
Reply #7 - Posted
2009-08-10 14:06:24 » |
|
For an explanation how to insert work into the display() call from outside, see http://www.java-gaming.org/topics/loading-shaders-possible-outside-of-gleventlistener-s-init-reshape-display/12475/msg/99927/view.html#msg99927. With this code you can do something like: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| actionPerformed(ActionEvent evt) { new Thread() { public void run() { final TextureData textureData = GLQueue.getInstance().add( new GLAction() { public void execute(GL target) { Texture texture = TextureIO.newTexture(texturedata); } }); }
}.start(); } |
Looks complicated, but as soon as you understood the pattern you can make yourself some utility methods to hide this complexity.
|
Mathias - I Know What [you] Did Last Summer!
|
|
|
Roxxor
Senior Newbie 
|
 |
«
Reply #8 - Posted
2009-08-20 15:33:11 » |
|
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/topics/loading-shaders-possible-outside-of-gleventlistener-s-init-reshape-display/12475/msg/99927/view.html#msg99927: 1 2 3 4 5 6 7 8 9
| 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: 1 2 3 4 5 6 7
| 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?
|
|
|
|
|
cylab
|
 |
«
Reply #9 - Posted
2009-08-23 22:24:31 » |
|
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 1
| ArrayList<GLAction> temp = new ArrayList<GLAction>(queue); |
You will have to type the queue list as well.
|
Mathias - I Know What [you] Did Last Summer!
|
|
|
Games published by our own members! Check 'em out!
|
|
spiraljetty
Senior Newbie 
|
 |
«
Reply #10 - Posted
2009-08-28 00:49:38 » |
|
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; 1 2 3 4 5 6 7
| 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): 1 2 3
| 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: 1
| AWTTextureData(int internalFormat, int pixelFormat, boolean mipmap, BufferedImage image, GLProfile profile) |
or 1
| AWTTextureData(int internalFormat, int pixelFormat, boolean mipmap, BufferedImage image, String profileStr) |
? -spiraljetty
|
|
|
|
|
cylab
|
 |
«
Reply #11 - Posted
2009-08-28 01:15:25 » |
|
You are right, the whole thing about TextureData was to separate texture preparation from the GL context. So I would consider this a bug.
|
Mathias - I Know What [you] Did Last Summer!
|
|
|
spiraljetty
Senior Newbie 
|
 |
«
Reply #12 - Posted
2009-08-28 01:52:47 » |
|
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
|
|
|
|
|
bienator
Senior Member   
OutOfCoffeeException
|
 |
«
Reply #13 - Posted
2009-08-28 02:03:49 » |
|
|
|
|
|
|
|
bienator
Senior Member   
OutOfCoffeeException
|
 |
«
Reply #15 - Posted
2009-08-28 02:26:09 » |
|
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)
|
|
|
|
spiraljetty
Senior Newbie 
|
 |
«
Reply #16 - Posted
2009-09-28 20:56:15 » |
|
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
|
|
|
|
|
|