Multithready between AWT and JOGL

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Multithready between AWT and JOGL

millerni456
Hello, I've got an incredibly difficult error and I'm not sure what is causing it.
I'm working on a pick selection component for a game, and I use a MouseListener to 'schedule a pick-selection' using boolean values. After a pick-selection is scheduled, the GLAutoDrawable.display() method will check to see if it is scheduled, and if so, it will perform a selection.

Here's the problem, when the MouseListener alters the boolean value, it cannot be read from the GLAutoDrawable.display() method. And vice-versa.

So far I have tried to make it a volatile variable, and that does NOT work. The only way I can get it to work is if I make it a static variable, which I do not want to do.

My guess is that the way I have my class set up does not mesh the two threads together in a good manner. So I'll try to define my programs layout.

MainClass: (implements GLEventListener)
-on the init() method, it will create "GLButton" objects. During this call, it gives a reference to the GLCanvas for each button in order to add extra MouseListeners later.
-on the display() method it will call a render method of a "GLButton" object

GLButton:
-when constructed it will store the GLCanvas variable sent to it inside a class-scope variable. Also during the construction, a new MouseListener is added to the GLCanvas. The implementation of the MouseListener is inside the GLButton object.
-when render(GL2 gl2) method is called, it will draw the button and check if a pick-selection has occurred. If so, it will perform a selection base on the Mouse's location.
-when the mousePressed() method is called, a pick-selection is scheduled and the mouse's location is stored.

Here is some code to see what I was trying to explain:


        public void mousePressed(MouseEvent e)
        {
                mouseLocation = e.getPoint();
                schedulePickSelection();
        }

        //this method schedules a pick-selection
        private synchronized void schedulePickSelection()//I probably don't even need it synchronized, just for debugging.
        {
                pickSchedule= true; //this is the class-scope variable to determine if a pick-selection is scheduled.
        }

Later in the render method I have an if-statement to check if a pick-selection is scheduled. Remember that the render method() is called by the GLAutoDrawable thread.

         if(isPickSelectionScheduled())
        {//isPickSelectionSchedule() is returns true if a selection is still scheduled.
               
                //reset the scedule (no longer scheduled)
                pickSchedule = false;
               
                //make a selection
                select(c, gl2);
        }

       private synchronized boolean isPickSelectionScheduled()//again unsure about the synchronized.
        {
                return pickSchedule; //returns the class-scope variable mentions earlier.
        }


And if there is any other information I should say in order to debug, let me know. One thing I should point out is that
I made a simple class to test this concept (without my whole game-structure) and everything worked fine. I didn't even have to declare volatile variables or synchronized methods. Just a MouseListener and the display() method.

If you would like more code just let me know.

Thanks for the help. Greatly appreciated. - Nick
Reply | Threaded
Open this post in threaded view
|

Re: Multithready between AWT and JOGL

millerni456
One quick fix (kinda a hack) is to change everything to orthogonal (which is the current mode) and just compare mouse coordinates with the coordinates of the button. But I would like to do this properly using the OpenGL selection methods. Thanks if you can solve the original question. But for now I'm going to stick with the hackish way.
Reply | Threaded
Open this post in threaded view
|

Re: Multithready between AWT and JOGL

Sven Gothel
Administrator
In reply to this post by millerni456
On Wednesday, September 21, 2011 11:35:36 PM Nick [via jogamp] wrote:
>
> Hello, I've got an incredibly difficult error and I'm not sure what is
> causing it.
> I'm working on a pick selection component for a game, and I use a
> MouseListener to 'schedule a pick-selection' using boolean values. After a
> pick-selection is scheduled, the GLAutoDrawable.display() method will check
> to see if it is scheduled, and if so, it will perform a selection.
>

long story short:
(as mentioned here: http://jogamp.org/jogl/doc/NEWT-Overview.html)

http://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/javax/media/opengl/GLAutoDrawable.html#invoke%28boolean,%20javax.media.opengl.GLRunnable%29
http://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/javax/media/opengl/GLRunnable.html
  http://jogamp.org/git/?p=jogl.git;a=blob;f=src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java;hb=HEAD#l203

Use 'GLAutoDrawable.invoke(GLRunnable)'
[for GLCanvas, GLWindow, ..]

We use this for our graph/UI false color picking algorithm and return false.

The idea is to inject this one shot GL runnable from another thread
not holding the GLContext.

Hope it helps.
Reply | Threaded
Open this post in threaded view
|

Re: Multithready between AWT and JOGL

millerni456
Good news is I think I understand what your post is about. I was able to create a window using the NEWT libraries and render a simple triangle. On the window (which was a JFrame) I had a JSlider that changed the field of view in the gluPerspective method. However when stateChanged() method is called from the slider, I invoke a new GLRunnable and execute the GLContext code in there.

On another note, should I be testing this with input (i.e. mouse/keyboard?) And what Ideas of integrating JInput with this?
I did attach a controller to an application I made but this made it lag alot. The controller only affected my camera which was updated under the GLContext thread.



EDIT: I actually wanted to ask if I can do something similar with the Android SDK, my plans eventually were to convert this JOGL application into an Android app. My guess is the Android threads work differently and allow for another way to catch input changes.


RE-Edit: Where can I find the NEWT javadocs?
Reply | Threaded
Open this post in threaded view
|

Re: Multithready between AWT and JOGL

Sven Gothel
Administrator
On Thursday, September 22, 2011 05:16:56 AM millerni456 [via jogamp] wrote:
>
> Good news is I think I understand what your post is about. I was able to
> create a window using the NEWT libraries and render a simple triangle. On
> the window (which was a JFrame) I had a JSlider that changed the field of
> view in the gluPerspective method. However when stateChanged() method is
> called from the slider, I invoke a new GLRunnable and execute the GLContext
> code in there.
>
great

> On another note, should I be testing this with input (i.e. mouse/keyboard?)
> And what Ideas of integrating JInput with this?
> I did attach a controller to an application I made but this made it lag
> alot. The controller only affected my camera which was updated under the
> GLContext thread.

Ok, now try to use NewtCanvasAWT to avoid any lag in the Animator
and rendering loop. Then you should be fine I hope.
(Due to the AWT EDT restriction)

If there is still a huge lag, we will work on it.

~Sven
Reply | Threaded
Open this post in threaded view
|

Re: Multithready between AWT and JOGL

millerni456
Hmm... although my original problem was not lag. I do get a lot of that when I populate my particles objects. I tried starting a new thread that manages updating of the particles while the GLAutoDrawable thread renders them using the particles statistics.

After changing to the NEWT implementation, however, I still cannot schedule a pick-selection. I even trying modifying the pick-Selection scheduling variable (boolean) inside the GLRunnable.run() method. Any Ideas?

I think the problem is that I still have two threads accessing two different values store in the same variable. For example, the variable is true on one thread, but it remains false on the other.
Reply | Threaded
Open this post in threaded view
|

Re: Multithready between AWT and JOGL

millerni456
I wonder if there is anything I can do with the following line:

GLContext context = GLDrawableFactory.getFactory().createExternalGLContext();

I would have to make the context available throughout my program, and I can call

context.makeCurrent();
context.release();

to control the OpenGL thread.
Reply | Threaded
Open this post in threaded view
|

Re: Multithready between AWT and JOGL

Sven Gothel
Administrator
In reply to this post by millerni456
On Friday, September 23, 2011 04:23:20 AM millerni456 [via jogamp] wrote:

>
> Hmm... although my original problem was not lag. I do get a lot of that when
> I populate my particles objects. I tried starting a new thread that manages
> updating of the particles while the GLAutoDrawable thread renders them using
> the particles statistics.
>
> After changing to the NEWT implementation, however, I still cannot schedule
> a pick-selection. I even trying modifying the pick-Selection scheduling
> variable (boolean) inside the GLRunnable.run() method. Any Ideas?
>
> I think the problem is that I still have two threads accessing two different
> values store in the same variable. For example, the variable is true on one
> thread, but it remains false on the other.

GLRunnable, GLEventListener accessing GL and your data
  -> If you use vars from the same thread, no need to sync them.

We do exactly that in our UI demo:
  http://jogamp.org/git/?p=jogl.git;a=blob;f=src/test/com/jogamp/opengl/test/junit/graph/demos/ui/SceneUIController.java;hb=HEAD#l208

  - Note we return false, which will lead to re-display the content normally.
  - Note we wait for GLRunnable to be done, hence implicit sync.

Well, I don't know your code so I don't know if you can use it this way.
Maybe you some synchronization.

Hope this helps.

~Sven
Reply | Threaded
Open this post in threaded view
|

Re: Multithready between AWT and JOGL

millerni456
Well here goes... that snippet you linked to me looks promising and I hope it works :)
Going to try returning false because my GLRunnable seemed to be blocking.
Edit: For some reason I cannot create the run() method with the return-type of boolean. Is there another way I can do this or is it possible I have the wrong version of JOGL?
Reply | Threaded
Open this post in threaded view
|

Re: Multithready between AWT and JOGL

millerni456
Here's my new code:


//this method is called via mouse click/press
public void schedulePickSelection()
{
    GLRunnable r = new GLRunnable()
    {
        public void run(GLAutoDrawable d)
        {
            select(d.getGL().getGL2());//this performs a selection in the OpenGL Context Thread.
        }
    }
}


Although this works fine, my code seems to get stuck  when I move the mouse (which triggers this method). It will perform the pick selection, but each time it picks, the moving geometry freezes, and sometimes this method will not stop calling.
Reply | Threaded
Open this post in threaded view
|

Re: Multithready between AWT and JOGL

Sven Gothel
Administrator
In reply to this post by millerni456
On Friday, September 23, 2011 09:08:43 PM millerni456 [via jogamp] wrote:
>
> Well here goes... that snippet you linked to me looks promising and I hope it
> works :)
> Going to try returning false because my GLRunnable seemed to be blocking.

GLRunnable.run(..) -> false has nothing todo w/ blocking,
but to issue a re-display before swapping.
This feature is required for eg. false-color rendering for picking.

If you can create a little test case (modify one of ours)
demonstrating the blocking, I may be able to help.

~Sven
Reply | Threaded
Open this post in threaded view
|

Re: Multithready between AWT and JOGL

Sven Gothel
Administrator
In reply to this post by millerni456
On Friday, September 23, 2011 09:22:12 PM millerni456 [via jogamp] wrote:

>
> Here's my new code:
>
>
> //this method is called via mouse click/press
> public void schedulePickSelection()
> {
>     GLRunnable r = new GLRunnable()
>     {
>         public void run(GLAutoDrawable d)
>         {
>             select(d.getGL().getGL2());//this performs a selection in the
> OpenGL Context Thread.
>         }
>     }
> }
http://jogamp.org/git/?p=jogl.git;a=blob;f=src/test/com/jogamp/opengl/test/junit/graph/demos/ui/SceneUIController.java;hb=HEAD#l208

 212             GLRunnable runnable = new GLRunnable() {
 213                 public boolean run(GLAutoDrawable drawable) {
 214                     UIShape s = getShape(drawable, mouseX, mouseY);
 215                     if(null != s) {
 216                         activeId = getShapes().indexOf(s);
 217                     }
 218                     else {
 219                         activeId = -1;
 220                     }
 221                     return false;
 222                 }
 223             };
 224             cDrawable.invoke(true, runnable);

You must use an old JOGL version, otherwise you couldn't compile it.
See the diff in the GLRunnable run methos signature,
return value 'void' versus 'boolean'.

Also you need to invoke it, best with wait==true (see above).

And if your picking uses false color, return false. (see last post)

>
>
> Although this works fine, my code seems to get stuck  when I move the mouse
> (which triggers this method). It will perform the pick selection, but each
> time it picks, the moving geometry freezes, and sometimes this method will
> not stop calling.

looks 'fishy' .. see above.

maybe you are able to send a little junit test here (see last post)

make sure you use the last JOGL, ie the just released beta 'jogamp-next'

~Sven