LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: EvilOne on April 14, 2010, 15:35:30

Title: AWTGLCanvas problem + question.
Post by: EvilOne on April 14, 2010, 15:35:30
Howdy,

I have a little problem with AWTGLCanvas. The rendering disappears after the execution of paintGL(). That is, the rendering takes place, after swapBuffers you see it for one frame and then it goes back to the components backcolor (that is, goes white). This can be solved by simply calling repaint() after buffer swap, to keep a steady repaint loop. But this isn't really the solution imho... The results of the last paint call should stay on screen, until the next painting is needed. Don't know if this is fixable.

Oh, and something completely different. I'm using the following code to do some rendering tasks using the context of the AWTGLPanel, synced on the AWT event thread. Is this the correct way to go?

Cheers,
E1.


/**
* Executes rendering on the AWT event thread.
*/
public final class GLExecutor implements Runnable
{
   /** The canvas to paint on. */
   private final AWTGLCanvas canvas;
   /** The runnable to execute. */
   private final Runnable runnable;
   /** Success. */
   private boolean success;
   
   /**
    * Creates a new executor.
    * @param canvas Canvas to paint on.
    * @param runnable Runnable to execute.
    */
   private GLExecutor(final AWTGLCanvas canvas, final Runnable runnable)
   {
      this.canvas   = canvas;
      this.runnable = runnable;
   }
   
   @Override
   public void run()
   {
      try
      {
         // Use the context.
         canvas.makeCurrent();
         
         // Execute.
         runnable.run();
         
         // Done.
         success = true;
      }
      catch(Exception e)
      {
         // Who cares.
         e.printStackTrace();
      }
   }
   
   /**
    * Executes the runnable.
    * @param canvas Canvas to paint on.
    * @param runnable Runnable to execute.
    */
   public final static boolean execute(final AWTGLCanvas canvas, final Runnable runnable)
   {
      try
      {
         // Inkvoke the executor.
         GLExecutor executor = new GLExecutor(canvas, runnable);
         EventQueue.invokeAndWait(executor);
         return executor.success;
      }
      catch(Exception e)
      {
         // Again, who cares.
         e.printStackTrace();
         
         // Failed.
         return false;
      }
   }
}


Title: Re: AWTGLCanvas problem + question.
Post by: broumbroum on April 14, 2010, 16:40:53
Quote... The results of the last paint call should stay on screen, until the next painting is needed. Don't know if this is fixable
I've been using AWTGLCanvas for a while. Canvas is rendered actively only, hence repaint should not be invoked, and hence you can disable passive rendering with Canvas.setIgnoreRepaint(true), this should fix that issue. ;)
QuoteIs this the correct way to go?
Yes,it is fully correct. EDT must be invoked. :D
Title: Re: AWTGLCanvas problem + question.
Post by: EvilOne on April 15, 2010, 12:49:03
Thanks.

But the question is, how to render correctly. Using setIgnoreRepaint(true) doesn't paint anything at all - that is, how do I trigger a repaint...

Cheers,
E1.
Title: Re: AWTGLCanvas problem + question.
Post by: broumbroum on April 15, 2010, 20:52:16
to repaint with AWTGLCanvas it's up to your renderer to run AWTGLCanvas.update(canvas.getGraphics()) and then swap buffers. Why using repaint if you are already running on EDT ?
QuoteThe results of the last paint call should stay on screen, until the next painting is needed
Or are you willing  to implement a passive rendering ? that is not actually possible, openGL overlays with a volatile fashion as you wrote :
QuoteThat is, the rendering takes place, after swapBuffers you see it for one frame and then it goes back to the components backcolor (that is, goes white)
So, there it is, what do you like ? 8)
Title: Re: AWTGLCanvas problem + question.
Post by: EvilOne on April 16, 2010, 12:11:02
What I am trying to do is using the GPU for computing, I have a large graph of connected filters, that do a render-to-texture. The GL canvas is just there for preview purposes, but most of the time not visible... everytime I need to do a computation, a runnable (via. GLExecutor) is invoked like:


@Override
void run()
{
    renderer.setFramebuffer(fb);
    renderer.begin();

    // Do some rendering to texture.

    renderer.end();
    renderer.setFramebuffer(null);
}


At least, thats the idea. Example: http://i41.tinypic.com/hw0d8j.png (http://i41.tinypic.com/hw0d8j.png)

The thing I was not sure about, is the correct rendering and interleaving between the canvas and the runnables. But what I do now is simply, if the canvas is visible, let it keep pumping via incremental repaint(), it's then in preview mode anyways, where the generated material is previewed on a mesh (gimme more teapots)... otherwise, just return immediately from paint. Works. If the preview is visible, the runnables get simply interleaved while rendering, otherwise the executor is invoked... Hope this is the correct thing to do.

The world is not only fullscreen apps!

Cheers,
E1.
Title: Re: AWTGLCanvas problem + question.
Post by: broumbroum on April 22, 2010, 20:11:40
I think FB is not necessary. I tried once ago with the FB, but was too hard to code and finally understood that FB Extension is intended to high end applications like a FPS Quake scene with virtual TVs spots or any samples of movies etc.
opengl can handle cached textures, real-time rendering, so fast that you can let your app refresh forever without overloading your cpu. => render to opengl in paintGL then call swapBuffers and IMMEDIATELY schedule the next render.
Use a java.util.Timer or Swing Timer (cos LWJGL needs edt  to render, right ?), and
QuoteIf the preview is visible, the runnables get simply interleaved while rendering, otherwise the executor is invoked...
Whatsoever you like... interleaving on swing is very handy, use swingUtilities, would you ?
:D