为什么当我要求30 FPS时,此代码有时会报告21.3 FPS?

时间:2012-10-17 14:32:05

标签: java opengl 3d jogl frame-rate

我有下面的代码(一个移植到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();
}

2 个答案:

答案 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