How do I force redraw of GLCanvas from another thread?

I’m developing a scientific application using jogl 2.0. I don’t need permanent/animator looping in OGL. GLCanvas has to be redrawn/repainted only on user demand, i.e. the user clicks on the JButton (e.g. Refresh) in main application and GLCanvas gets repainted.

I have read that jogl 2.0 event thread is synchronized with AWT event queue thread, so if I understood it well, I could call e.g.

glCanvas.display();

from main application loop (outside of any GLEventLIsteners) without any problems. I did it that way. Compiled without errors, but nothing happens. It seems that call to dispaly() is ignored.

What is the problem? How can I resolve this?

Hi

At first, if you need some help on JOGL, rather post on jogamp.org.

I don’t reproduce your problem, I use a modified animator that calls display() only when a flag is set to true (and I disable auto swap mode). Tell me whether you need a more complete example.

I posted here because I have read this in official JOGL Userguide: [quote]The JOGL forum on javagaming.org is the best place to ask questions about the library. Many users, as well as the Jogl developers, read this forum frequently, and the archived threads contain a lot of useful information (which still needs to be distilled into documentation).
[/quote]
Yes, I would appreciate on more complete example, but first I’ll be more concrete with my problem. Maybe you’'ll figure out what I did wrong.


public class MainFrame extends JFrame implements ActionListener {
  JButton jb_refresh = new JButton("Refresh");
  OpenGLCanvas openGLCanvas;
  ...
  public MainFrame() {
        openGLCanvas = new OpenGLCanvas(this);
        ...
        jb_refresh.addActionListener(this);
        getContentPane().add(jb_refresh, BorderLayout.NORTH);
        getContentPane().add(openGLCanvas.getGlCanvas(), BorderLayout.CENTER);
  }
  ...
  public void actionPerformed(ActionEvent e) {
    // some calcs to set new values in 
    ...
    openGLCanvas.getGl_canvas().display();
    openGLCanvas.getGl_canvas().requestFocusInWindow();
  }
  ...
  // main method etc.
}


public class OpenGLCanvas implements GLEventListener, KeyListener, MouseListener, MouseMotionListener, MouseWheelListener {
  MainFrame frame;
  GLCanvas glCanvas;

  public OpenGLCanvas(MainFrame frame) {
        this.frame = frame;
        initContent();
    }

    private void initContent() {
        GLProfile glprofile = GLProfile.getDefault();
        GLCapabilities glcapabilities = new GLCapabilities(glprofile);
        glCanvas = new GLCanvas(glcapabilities);
        glCanvas.addGLEventListener(this);
        glCanvas.addKeyListener(this);
        glCanvas.addMouseListener(this);
        glCanvas.addMouseMotionListener(this);
        glCanvas.addMouseWheelListener(this);
    }

    public GLCanvas getGlCanvas() {
        return glCanvas;
    }

   public void init(GLAutoDrawable glAutoDrawable) {
      ...
   }

   public void display(GLAutoDrawable glAutoDrawable) {
      ...
   }

   public void dispose(GLAutoDrawable glAutoDrawable) {
      ...
   }

   public void reshape(GLAutoDrawable glAutoDrawable, int x, int y, int width, int height) {
      ...
   }

   ...

}

Which build of JOGL do you use? Actually the canvas will be refreshed if you do not disable auto swap buffer mode. You can find some source code in this bug report:
https://jogamp.org/bugzilla/show_bug.cgi?id=455

You can override the class Animator to add a flag to tell whether a redraw is really needed. Then, when you press a button, you could set this flag to true. When the animator is called, it checks the flag, it redraws everything it is set to true and then it sets it back to false. It was working fine in JOGL 1.1.1a but a nasty bug increases the memory consumption in JOGL 2 when calling setAutoSwapBufferMode(true) on a GLCanvas.

I’m using jogl-2.0-b23-20110303 build.

I added and started animator just to check if it’s gonna be of any use, and no, nothing new happend. :frowning: I’m newbie to jogl, so here is updated code so you can check if I had done everything OK.


public class OpenGLCanvas implements GLEventListener, KeyListener, MouseListener, MouseMotionListener, MouseWheelListener {
  MainFrame frame;
  GLCanvas glCanvas;
  Animator animator;
 
  public OpenGLCanvas(MainFrame frame) {
        this.frame = frame;
        initContent();
    }
 
    private void initContent() {
        GLProfile glprofile = GLProfile.getDefault();
        GLCapabilities glcapabilities = new GLCapabilities(glprofile);
        glCanvas = new GLCanvas(glcapabilities);
        glCanvas.addGLEventListener(this);
        glCanvas.addKeyListener(this);
        glCanvas.addMouseListener(this);
        glCanvas.addMouseMotionListener(this);
        glCanvas.addMouseWheelListener(this);
        animator = new Animator(glCanvas);
        animator.start();
    }
 
    public GLCanvas getGlCanvas() {
        return glCanvas;
    }
 
   public void init(GLAutoDrawable glAutoDrawable) {
      ...
   }
 
   public void display(GLAutoDrawable glAutoDrawable) {
      ...
   }
 
   public void dispose(GLAutoDrawable glAutoDrawable) {
      ...
      animator.stop();
   }
 
   public void reshape(GLAutoDrawable glAutoDrawable, int x, int y, int width, int height) {
      ...
   }
 
   ...
 
}

What do you mean by nothing happens? Does no window show up? Or will the window be blank? Were ever able to get things to show up, before trying to call display() directly?

You are correct in assuming that you can call display() to make it redraw everything on the AWT thread automatically.

Have you looked at the simple example I posted on Wikipedia?

P.S: please use a more recent build (the build 367 for example).

Thank you very much. It works with build 367.

You’re welcome :slight_smile: Your previous build contains some major bugs that have been fixed.