display() called repeatedly, yet screen not updated?

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

display() called repeatedly, yet screen not updated?

jerron
Hello.

I have the following:

--

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.fixedfunc.GLMatrixFunc;

import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.FPSAnimator;

public final class JavaGL1 implements GLEventListener, KeyListener
{
  static {
    GLProfile.initSingleton();
  }

  private static void initGL()
  {
    final GLProfile profile = GLProfile.getDefault();
    final GLCapabilities capabilities = new GLCapabilities(profile);
    final GLWindow window = GLWindow.create(capabilities);

    window.setSize(300, 300);
    window.setVisible(true);
    window.setTitle("NEWT Window Test");
    window.addWindowListener(new WindowAdapter() {
      @Override public void windowDestroyNotify(final WindowEvent arg0)
      {
        System.exit(0);
      }
    });

    final JavaGL1 test0 = new JavaGL1();
    window.addGLEventListener(test0);
    window.addKeyListener(test0);

    final Animator animator = new FPSAnimator(window, 30);
    animator.add(window);
    animator.start();
  }

  public static void main(final String[] args)
  {
    JavaGL1.initGL();
  }

  @Override public void dispose(final GLAutoDrawable drawable)
  {
    System.out.println("info: dispose");
  }

  @Override public void init(final GLAutoDrawable drawable)
  {
    System.out.println("info: init");
  }

  private void perspective (final GL2 gl, double width, double height, double fov_y, double z_near, double z_far)
  {
    final double aspect_ratio = width / height;
    final double fr_height = Math.tan(fov_y / 360 * Math.PI) * z_near;
    final double fr_width = fr_height * aspect_ratio;
    gl.glFrustum(-fr_width, fr_width, -fr_height, fr_height, z_near, z_far);
  }
 
  int screen_width = 0;
  int screen_height = 0;
 
  private float cam_pos_x = 0.0f;
  private float cam_pos_y = 0.0f;
  private float cam_pos_z = -50.0f;

  private void location()
  {
    System.out.println("info: location: x: " + this.cam_pos_x + " y: " + this.cam_pos_y + " z: " + this.cam_pos_z);
  }

  private void render(final GL2 gl)
  {
    System.out.println("info: render");
   
    gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
    gl.glLoadIdentity();
    this.perspective(gl, this.screen_width, this.screen_height, 45.0, 0.1, 100.0);
   
    gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
    gl.glLoadIdentity();

    gl.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    gl.glClear(GL.GL_COLOR_BUFFER_BIT);

    gl.glTranslatef(0.0f, 0.0f, -50.f);
    gl.glColor3f((float) Math.random(), (float) Math.random(), (float) Math.random());
    gl.glBegin(GL.GL_TRIANGLES);
    gl.glVertex3f(this.cam_pos_x, this.cam_pos_y, 0.0f);
    gl.glVertex3f(this.cam_pos_x, this.cam_pos_y + 20.f, 0.0f);
    gl.glVertex3f(this.cam_pos_x + 20.f, this.cam_pos_y, 0.0f);
    gl.glEnd();
  }

  @Override public void display(final GLAutoDrawable drawable)
  {
    final GL2 gl = drawable.getGL().getGL2();
    this.render(gl);
  }

  @Override public void reshape(final GLAutoDrawable drawable,
                                final int x,
                                final int y,
                                final int width,
                                final int height)
  {
    System.out.println("info: resize " + x + "," + y + "+" + width + "x" + height);
   
    this.screen_width = width;
    this.screen_height = height;
   
    final GL2 gl = drawable.getGL().getGL2();
    gl.glViewport(0, 0, width, height);
  }

  @Override public void keyPressed(final KeyEvent arg0)
  {
    // Nothing.
  }

  @Override public void keyReleased(final KeyEvent event)
  {
    System.out.println("info: key " + event.getKeyChar());

    switch (event.getKeyChar()) {
      case 'w':
        this.cam_pos_z += 10.0f;
        break;
      case 's':
        this.cam_pos_z -= 10.0f;
        break;
      case 'a':
        this.cam_pos_x += 10.0f;
        break;
      case 'd':
        this.cam_pos_x -= 10.0f;
        break;
      case 'f':
        this.cam_pos_y += 10.0f;
        break;
      case 'v':
        this.cam_pos_y -= 10.0f;
        break;
      default:
        break;
    }

    this.location();
  }

  @Override public void keyTyped(final KeyEvent arg0)
  {
    // Nothing.
  }
}

--

Running this program, I'd expect to see a triangle onscreen changing color at random.

Instead, the triangle appears but the screen never seems to be updated after that. Adding
TraceGL or just some simple print statements shows that display() is called repeatedly but
it apparently has no effect. Any idea what might be going on?
Reply | Threaded
Open this post in threaded view
|

Re: display() called repeatedly, yet screen not updated?

gouessej
Administrator
Hi!

Which build of JOGL 2.0 do you use?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: display() called repeatedly, yet screen not updated?

jerron
Hello.

I installed an OS package (I couldn't get the source to build for whatever reason)
which appears to be "2.0.20100914". OS is FreeBSD 8.2 amd64. java -version says:

openjdk version "1.6.0"
OpenJDK Runtime Environment (build 1.6.0-b22)
OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode)
Reply | Threaded
Open this post in threaded view
|

Re: display() called repeatedly, yet screen not updated?

jerron
I'm now using the latest build from git and have come up with a cut down version of the above that demonstrates a strange timing issue:

--

package com.io7m.javagl1;

import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;

import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.FPSAnimator;

public final class JavaGL1 implements GLEventListener
{
  static {
    GLProfile.initSingleton(true);
  }

  private static void initGL()
  {
    final GLProfile profile = GLProfile.getDefault();
    final GLCapabilities capabilities = new GLCapabilities(profile);
    final GLWindow window = GLWindow.create(capabilities);

    window.setSize(300, 300);
    window.setVisible(true);
    window.setTitle("NEWT Window Test");
    window.addWindowListener(new WindowAdapter() {
      @Override public void windowDestroyNotify(final WindowEvent arg0)
      {
        System.exit(0);
      }
    });

    final JavaGL1 test0 = new JavaGL1();
    window.addGLEventListener(test0);

    final FPSAnimator animator = new FPSAnimator(window, 1);
    animator.add(window);
    animator.start();
  }

  public static void main(final String[] args)
  {
    JavaGL1.initGL();
  }

  @Override public void dispose(final GLAutoDrawable drawable)
  {
    System.out.println("info: dispose");
  }

  @Override public void init(final GLAutoDrawable drawable)
  {
    System.out.println("info: init - autoswap(" + drawable.getAutoSwapBufferMode() + ")");
  }

  @Override public void display(final GLAutoDrawable drawable)
  {
    System.out.println("info: display " + System.currentTimeMillis());
  }

  @Override public void reshape(final GLAutoDrawable drawable,
                                final int x,
                                final int y,
                                final int width,
                                final int height)
  {
    System.out.println("info: resize " + x + "," + y + "+" + width + "x" + height);
  }
}

--

The output of the program is:

Info: XInitThreads() called for concurrent Thread support
Detected screen size 2880x900
info: init - autoswap(true)
info: resize 0,0+1438x438
info: display 1306338624188
info: display 1306338624193
info: display 1306338625187
info: display 1306338625192
info: display 1306338626189
info: display 1306338626196
info: display 1306338627190
info: display 1306338627195
info: display 1306338628191
info: display 1306338628196
info: display 1306338629192
info: display 1306338629197
info: display 1306338630193
info: display 1306338630198
info: display 1306338631195
info: display 1306338631200
info: display 1306338632196
info: display 1306338632201
info: display 1306338633197
info: display 1306338633202
info: display 1306338634198
info: display 1306338634203
info: display 1306338635198
info: display 1306338635203
info: display 1306338636200
info: display 1306338636205
info: display 1306338637202
info: display 1306338637209
info: dispose
Warning: EDT about (2) to stop, having remaining tasks: 1 - Thread[main-Display-X11_:0.0-1-EDT-1,5,main]

Note that given the 'new FPSAnimator(window, 1);', display should be called once per second, but it's
being called twice in quick succession, milliseconds apart, each second. I believe this could be the cause of the screen update issues but I don't know how to fix it.
Reply | Threaded
Open this post in threaded view
|

Re: display() called repeatedly, yet screen not updated?

jerron
Another case using explicit swapBuffer() calls, still the same issue. The first frame is
rendered, no subsequent frames are (the OpenGL calls take place but nothing on the
screen changes, suggesting some sort of buffer issue).

--

package com.io7m.javagl1;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.fixedfunc.GLMatrixFunc;

import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;

public final class JavaGL2 implements GLEventListener
{
  static {
    GLProfile.initSingleton(true);
  }

  private static void initGL()
  {
    final GLProfile profile = GLProfile.getDefault();
    final GLCapabilities capabilities = new GLCapabilities(profile);
    final GLWindow window = GLWindow.create(capabilities);

    window.setSize(300, 300);
    window.setVisible(true);
    window.setTitle("NEWT Window Test");
    window.addWindowListener(new WindowAdapter() {
      @Override public void windowDestroyNotify(final WindowEvent arg0)
      {
        System.exit(0);
      }
    });

    final JavaGL2 test0 = new JavaGL2();
    window.addGLEventListener(test0);

    while (true) {
      System.out.println("info: sleeping");
      try {
        Thread.sleep(1000);
        System.out.println("info: awoke, rendering");
        window.display();
        window.swapBuffers();
      } catch (final InterruptedException e) {
        // Don't care.
      }
    }
  }

  public static void main(final String[] args)
  {
    JavaGL2.initGL();
  }

  @Override public void dispose(final GLAutoDrawable drawable)
  {
    System.out.println("info: dispose - autoswap(" + drawable.getAutoSwapBufferMode() + ")");
  }

  @Override public void init(final GLAutoDrawable drawable)
  {
    drawable.setAutoSwapBufferMode(false);
    System.out.println("info: init - autoswap(" + drawable.getAutoSwapBufferMode() + ")");
  }

  private void render(final GL2 gl)
  {
    System.out.println("info: render " + System.nanoTime());

    gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
    gl.glLoadIdentity();
    gl.glOrtho(0.0, 1.0, 0.0, 1.0, 0.1, 100.0);

    gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
    gl.glLoadIdentity();

    gl.glClearColor((float) Math.random(), (float) Math.random(), (float) Math.random(), 1.0f);
    gl.glClear(GL.GL_COLOR_BUFFER_BIT);
  }

  @Override public void display(final GLAutoDrawable drawable)
  {
    System.out.println("info: display " + System.nanoTime());
    this.render(drawable.getGL().getGL2());
  }

  @Override public void reshape(final GLAutoDrawable drawable,
                                final int x,
                                final int y,
                                final int width,
                                final int height)
  {
    System.out.println("info: resize " + x + "," + y + "+" + width + "x" + height);
    final GL2 gl = drawable.getGL().getGL2();
    gl.glViewport(0, 0, width, height);
  }
}
Reply | Threaded
Open this post in threaded view
|

Re: display() called repeatedly, yet screen not updated?

gouessej
Administrator
In reply to this post by jerron
What happens if you replace the FPSAnimator by a simple Animator + V-sync (setSwapInterval)?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: display() called repeatedly, yet screen not updated?

Worker
In reply to this post by jerron
Try it at the end from your display method with a
gl.glFlush();
Reply | Threaded
Open this post in threaded view
|

Re: display() called repeatedly, yet screen not updated?

Worker
In reply to this post by gouessej
Yes, that works.
I calculate my refresh rates dynamic at runtime, so i have always
good balanced refresh rates.
 
Reply | Threaded
Open this post in threaded view
|

Re: display() called repeatedly, yet screen not updated?

jerron
In reply to this post by jerron
Hi.

I spoke to Michael Bien a couple of days ago and we seem to be in agreement that this is a bug on FreeBSD. I'm currently waiting for Sven to return from wherever he is, as he apparently knows more about it.
Reply | Threaded
Open this post in threaded view
|

Re: display() called repeatedly, yet screen not updated?

Sven Gothel
Administrator
On Saturday, May 28, 2011 04:12:55 pm jerron [via jogamp] wrote:
>
> Hi.
>
> I spoke to Michael Bien a couple of days ago and we seem to be in agreement
> that this is a bug on FreeBSD. I'm currently waiting for Sven to return from
> wherever he is, as he apparently knows more about it.

I am back .. from wherever I was :)

OFC .. let's chat about the issue, we may also be able to setup a FreeBSD box,
since it is an important target IMHO.

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

Re: display() called repeatedly, yet screen not updated?

charlie
This post was updated on .
In reply to this post by jerron
Hi,
I seem to be experiencing a similar problem that seems to be related, though not identical to the issue described.

My code is pretty basic - adds a GLEventListener to a NEWT window, which just draws a shaded, rotated square. I've tried looping through {window.display()/println("Tick")}, and using an FPSAnimator, but in both situations the animation will run for a few hundred frames then freeze completely, until I wave the mouse or press a key. It appears that the window.display() routine is delaying - I don't see the "Tick" message until after moving the mouse . Adding a glFlush() to the end of the draw code has no effect.

I can't see anything obviously wrong with my code, it's pretty much verbatim from a demo, and works perfectly whilst a key is held down or the mouse is waved.

Running on Ubuntu 11.04/x86, NVidia drivers/GO 6800 (NOT GMA950 as first stated), latest JDK, Eclipse, JOGL/NEWT built from GIT a couple of days ago. Will try on Win7/x64 or WinXP/x86 some point in the near future.


EDIT 4th July:

Not a GMA950, sorry - it's a Go 6800.

I tested the same code (except for the JOGL version - using the signed release) on my Win64 machine and no such issue existed. Does anyone have an idea what might be causing this issue?