问题描述
我有一个通过 Android 中的 JNI 运行的 C++ 游戏.由于场景复杂性,帧速率在 20-45fps 之间变化.任何高于 30fps 的速度对游戏来说都是愚蠢的;它只是在烧电池.我想将帧速率限制为 30 fps.
I have a C++ game running through JNI in Android. The frame rate varies from about 20-45fps due to scene complexity. Anything above 30fps is silly for the game; it's just burning battery. I'd like to limit the frame rate to 30 fps.
- 我可以切换到 RENDERMODE_WHEN_DIRTY,并使用 Timer 或 ScheduledThreadPoolExecutor 来 requestRender().但这会增加一大堆额外的移动部件,这些部件可能会或可能不会始终如一地正常工作.
- 我尝试在事情快速运行时注入 Thread.sleep() ,但这对于小时间值似乎根本不起作用.而且它可能只是将事件支持到队列中,而不是真正暂停.
API 中是否隐藏了capFramerate()"方法?有什么可靠的方法吗?
Is there a "capFramerate()" method hiding in the API? Any reliable way to do this?
推荐答案
Mark 的解决方案几乎不错,但并不完全正确.问题是交换本身需要相当长的时间(特别是如果视频驱动程序正在缓存指令).因此,您必须考虑到这一点,否则您将以低于预期的帧速率结束.所以事情应该是:
The solution from Mark is almost good, but not entirely correct. The problem is that the swap itself takes a considerable amount of time (especially if the video driver is caching instructions). Therefore you have to take that into account or you'll end with a lower frame rate than desired.So the thing should be:
一开始的某处(如构造函数):
somewhere at the start (like the constructor):
startTime = System.currentTimeMillis();
然后在渲染循环中:
public void onDrawFrame(GL10 gl)
{
endTime = System.currentTimeMillis();
dt = endTime - startTime;
if (dt < 33)
Thread.Sleep(33 - dt);
startTime = System.currentTimeMillis();
UpdateGame(dt);
RenderGame(gl);
}
这样您将考虑交换缓冲区所需的时间和绘制帧的时间.
This way you will take into account the time it takes to swap the buffers and the time to draw the frame.
这篇关于使用 Android 的 GLSurfaceView.RENDERMODE_CONTINUOUSLY 时如何限制帧率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!