Hi Ken,
Yes I’ve just found the root of the problem.
First use the attached source below:
`
package experiments;
import java.awt.BorderLayout;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import net.java.games.jogl.Animator;
import net.java.games.jogl.GL;
import net.java.games.jogl.GLCanvas;
import net.java.games.jogl.GLCapabilities;
import net.java.games.jogl.GLDrawable;
import net.java.games.jogl.GLDrawableFactory;
import net.java.games.jogl.GLEventListener;
import net.java.games.jogl.GLU;
public class SmoothScrollJOGL2
extends JFrame
implements KeyListener, GLEventListener
{
GraphicsDevice device;
GLCanvas canvas;
Animator animator;
JLabel label = new JLabel("hahaha");
long elapsedStart;
double elapsedSecond;
/**
* Constructor.
*
*/
public SmoothScrollJOGL2()
{
device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
canvas.addGLEventListener(this);
setUndecorated(true);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(canvas, BorderLayout.CENTER);
getContentPane().add(label, BorderLayout.SOUTH);
animator = new Animator(canvas);
device.setFullScreenWindow(this);
elapsedStart = System.nanoTime();
animator.start();
addKeyListener(this);
}
public void keyTyped(KeyEvent e) {}
public void keyPressed(KeyEvent e) {}
public void keyReleased(KeyEvent e)
{
new Thread(new Runnable()
{
public void run()
{
animator.stop();
System.exit(0);
}
}).start();
}
public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
public void init(GLDrawable drawable) {}
public void reshape(GLDrawable drawable, int x, int y, int width, int height)
{
GL gl = drawable.getGL();
GLU glu = drawable.getGLU();
// turn on vsync, just to be sure
gl.wglSwapIntervalEXT(1);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
// choose major depending on which axis is bigger
if(width > height)
{
float AR = (float)height / width; // width-major
gl.glOrtho(-1f, +1f, // left, right
-AR, +AR, // bottom, top
-1f, +1f); // near, far
}
else
{
float AR = (float)width / height; // height-major
gl.glOrtho(-AR, +AR, // left, right
-1f, +1f, // bottom, top
-1f, +1f); // near, far
}
System.out.println("reshape(): " + width + "," + height);
}
public void display(GLDrawable drawable)
{
elapsedSecond = (System.nanoTime() - elapsedStart) / 1000000000.0;
GL gl = drawable.getGL();
GLU glu = drawable.getGLU();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glColor3f(1,1,1);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
gl.glTranslatef((float)Math.sin(elapsedSecond), 0, 0);
float x = 0.1f / 2;
float y = 2 / 2;
gl.glBegin(GL.GL_QUADS);
gl.glVertex3f(-x, -y, 0); // BL
gl.glVertex3f(+x, -y, 0); // BR
gl.glVertex3f(+x, +y, 0); // TR
gl.glVertex3f(-x, +y, 0); // TL
gl.glEnd();
SwingUtilities.invokeLater(new Runnable() { public void run() { label.setText(""+elapsedSecond); } });
}
public static void main(String[] args)
{
new SmoothScrollJOGL2();
}
}
`
If you run this in “jogl.1thread=true” mode
you will notice very bad skipping frames.
When in “jogl.1thread=false” mode it will be
smoother but still skip frames regularly.
Now add the following code snippet at the
start of net.java.games.jogl.GLCanvas.reshape():
`
public void reshape(int x, int y, int width, int height)
{
if(width == getWidth() &&
height == getHeight() &&
x == getX() &&
y == getY())
{
return;
}
`
Now run the test app in “jogl.1thread=false”
mode and you should see no more skipped
frames. If “jogl.1thread=true” then there will
still be occasional skip frames. I’ve tested this
on a nVidia 6600GT with latest drivers (71.84)
and on a mobile ATI X700 with bundled drivers
and it works. I’ve also collected timing data
and plotted Excel charts to show the stability
of the frames.
This usage scenario comes up when using JOGL
in any type of editor-type app with real-time
previewing and the skip frames is really quite
unacceptable. I think the way to solve it is
not to make the rendering happen on the
AWT thread but on a user-defined thread.
.rex