我有下面的代码(一个移植到JOGL 2.0的简单版本的Nehe教程1),它正在请求一个动画为30 FPS的FPSAnimator。当我运行代码时,它打印21.321962或21.413277 FPS。在创建FPSAnimator时,如您所见,我指定每秒30帧。这是一台配备Core i7 CPU,24GB RAM和ATI Radeon HD 5700系列显卡的现代机器。 21.3 FPS似乎也不是限制。当我提高或降低请求的FPS时,报告的FPS确实上下波动(尽管它看起来不是线性关系)。
但是,有时当我在同一台机器上运行代码时,会给我30.30303 FPS。在这两种情况下,我只有几个Web浏览器选项卡和机器上的eclipse打开。值得注意的是,这不仅发生在这个简单的例子中,它发生在我所有基于JOGL的应用程序中。我只提供了这个简单的例子来证明这个问题。
我在几台机器上看到过这个问题。也许这只是我的想象力,但它似乎不会出现在配备NVidia GeForce显卡的机器上,但我已经看到它出现在配备ATI显卡和NVidia Quadro FX卡的机器上。
可能导致这种差异的原因是什么?
public static void main(String[] args) {
GLCanvas glCanvas;
FPSAnimator animator;
JFrame frame = new JFrame("JOGL HelloWorld");
GLCapabilities caps = new GLCapabilities(null);
caps.setDoubleBuffered(true);
caps.setHardwareAccelerated(true);
glCanvas = new GLCanvas(caps);
glCanvas.setSize(800, 800);
glCanvas.setIgnoreRepaint(true);
glCanvas.addGLEventListener(new GLEventListener() {
@Override
public void reshape(GLAutoDrawable gLDrawable, int x, int y,
int width, int height) {
}
@Override
public void init(GLAutoDrawable gLDrawable) {
}
@Override
public void dispose(GLAutoDrawable gLDrawable) {
}
@Override
public void display(GLAutoDrawable gLDrawable) {
FPSAnimator animator = (FPSAnimator) gLDrawable.getAnimator();
System.out.println("animator.getLastFPS(): "
+ animator.getLastFPS());
}
});
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(glCanvas, BorderLayout.CENTER);
animator = new FPSAnimator(glCanvas, 30, false);
frame.setSize(frame.getContentPane().getPreferredSize());
frame.setVisible(true);
animator.setUpdateFPSFrames(10, null);
animator.start();
}
答案 0 :(得分:2)
问题可能是由与java.util.Timer.schedule()
相关的不准确引起的,JOGL在使用任何双参数构造函数初始化时使用,或者第3个参数,这是使用固定速率的标志计划,设置为false
。
当标志设置为true
时,FPSAnimator将改为使用java.util.Timer.scheduleAtFixedRate()
,在FPS方面更加一致和准确。
具体而言,使用标记为true
在更高的FPS中会更好,因为默认情况下延迟较弱并且会开始遭受漂移,而使用固定速率调度将执行动画在很长一段时间内的正确次数,无论延迟 [source]。
但请注意,根据对ticket responsible for this functionality being implemented的响应,不清楚该标志是否会导致过多的CPU消耗。
答案 1 :(得分:0)
请求30 fps不保证。 FPS将几乎总是更低或更高,但avg fps将尝试按要求。
可以通过gl.setSwapInterval(1)启用VSync,与Windows设置无关。
使用animator.setUpdateFPSFrames(200,System.out);每200帧打印avg fps