【问题标题】:Android -- putting the GLSurfaceView.Renderer to sleep (as in Thread.sleep(20)) outside of the OnDrawFrame MethodAndroid - 在 OnDrawFrame 方法之外让 GLSurfaceView.Renderer 进入睡眠状态(如在 Thread.sleep(20) 中)
【发布时间】:2011-12-08 04:13:30
【问题描述】:

我想控制我的 GLSurfaceView.Renderer 的渲染速率。我在扩展 GLSurfaceView 的类中实现了一个线程,并在 while(true) 循环中定期将其置于睡眠状态,这并没有降低渲染器的速度。有一个很好的答案here 建议通过在 Renderer.onDrawFrame() 方法中使用 Thread.sleep 使 GL 线程进入睡眠状态。我想从 Renderer 类之外处理它。当显式调用需要传入 GL10 对象时,如何做到这一点?谢谢。

【问题讨论】:

  • 这听起来微不足道,但一旦 onDrawFrame 下次被调用就让它休眠是完全没有问题的——这意味着你可以设置一个标志让它发生?

标签: java android multithreading graphics opengl-es


【解决方案1】:

不要扩展 GLSurfaceView。如果您还没有,请将渲染器作为变量保留在您的活动类中:

public class MyActivity extends Activity {

    protected GLSurfaceView mGLView;
    protected GraphicsRenderer graphicsRenderer; // keep reference to renderer

    protected void initGraphics() {

        graphicsRenderer = new GraphicsRenderer(this);

        mGLView = (GLSurfaceView) findViewById(R.id.graphics_glsurfaceview1);
        mGLView.setEGLConfigChooser(true);         
        mGLView.setRenderer(graphicsRenderer);

        graphicsRenderer.setFrameRate(30);


    }
}

然后你可以在你的渲染器中创建一个方法来控制帧率:

public class GraphicsRenderer  implements GLSurfaceView.Renderer {

    private long framesPerSecond;
    private long frameInterval; // the time it should take 1 frame to render
    private final long millisecondsInSecond = 1000;

    public void setFrameRate(long fps){

        framesPerSecond = fps;

        frameInterval= millisecondsInSeconds / framesPerSecond;

    }


    public void onDrawFrame(GL10 gl) {

        // get the time at the start of the frame
        long time = System.currentTimeMillis();

        // drawing code goes here

        // get the time taken to render the frame       
        long time2 = System.currentTimeMillis() - time;

        // if time elapsed is less than the frame interval
        if(time2 < frameInterval){          
            try {
                // sleep the thread for the remaining time until the interval has elapsed
                Thread.sleep(frameInterval - time2);
            } catch (InterruptedException e) {
                // Thread error
                e.printStackTrace();
            }
        } else {
            // framerate is slower than desired
        }
    }

}

【讨论】:

  • 停止 onDrawFrame() 可能有问题。最新版本的 Android 将 onDrawFrame() 与设备上的“vsync”刷新同步,因此如果 sleep() 调用恰好在下一帧的边缘结束,这可能会导致动画不连贯。由于 onDrawFrame() 由外部时钟驱动,因此您控制帧速率的能力基本上仅限于每 N 次刷新渲染一次(例如,每隔一次绘制一次 onDrawFrame 被调用以将更新减半)。 sleep() 可能并不完全准确。
  • 好点。我可以发誓有一种方法可以向渲染器提示您想要的帧速率,但我现在找不到任何信息。对于我自己的引擎,我不控制帧率,我只是让它继续它,但有些人想要更多的控制
  • 如果您的游戏状态更新相对不频繁,您可以将渲染器放入RENDERMODE_WHEN_DIRTY,只要有新的东西要绘制,您就可以将其放入requestRender()
  • 这个思路不错,要实现更多,需要 1. 设置 RENDERMODE_WHEN_DIRTY 2. 将起始线程和 thread.sleep 移到其他线程 3. 调用 requestRender() 手动重新加载跨度>
猜你喜欢
  • 2011-05-12
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多