2

我有下面的代码(移植到 JOGL 2.0 的 Nehe 教程 1 的基本版本),它请求一个 FPSAnimator 动画 30 FPS。当我运行代码时,它会打印 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();
}
4

2 回答 2

2

问题可能是由与 相关的不准确性引起的java.util.Timer.schedule(),JOGL 在使用任何双参数构造函数初始化时,或者当第 3 个参数(使用固定速率调度的标志)设置为时,会使用该不准确性false


当标志设置为 时true,FPSAnimator 将java.util.Timer.scheduleAtFixedRate()改为使用,在 FPS 方面更加一致和准确。

具体来说,使用标志 astrue在更高的 FPS 中会特别好,因为默认值对延迟很弱并且会开始出现漂移,而使用固定速率调度将在很长一段时间内以正确的次数执行动画,不管延迟 [来源]


但是请注意,根据对正在实现此功能的票证的响应尚不清楚该标志是否会导致 CPU 消耗过多。

于 2012-10-18T18:59:36.847 回答
0

不保证请求的 30 fps。FPS 几乎总是会更低或更高,但 avg fps 会尽量满足要求。

VSync 可以通过 gl.setSwapInterval(1) 启用,与 windows 设置无关。

使用 animator.setUpdateFPSFrames(200, System.out); 每 200 帧打印 avg fps

于 2012-10-18T16:19:01.227 回答