一段时间以来,我经历了Android游戏中运动的小 Sprite 的间歇性“停顿”。这是一个非常简单的2D OpenGL ES 2.0游戏。 (这是一个持续存在的问题,我已经多次进行了访问)。
在我的游戏循环中,我有2个“计时器”-一个会记录前一秒的帧数,另一个会记录从当前onDrawFrame迭代结束到下一个开始的时间(以毫秒为单位)。
这是我发现的:
当不渲染任何东西时,我得到60fps(大部分情况下),并且每次调用onDrawFrame时,它报告自己花费的时间都超过了16.667ms。现在,如果我渲染某些东西(不管是1个四边形还是100个四边形,结果都是一样的),我将获得60fps(大部分情况下),但是现在,只有大约20%的onDrawFrame调用报告自己花费了更长的时间比上次通话时间长16.667毫秒。
我真的不明白为什么会发生这种情况,首先,为什么当onDrawFrame不执行任何操作时,它为什么被称为“缓慢”?更重要的是,为什么任何GL调用(一个简单的四边形)仍然使两者之间的时间间隔onDrawFrame调用的时间长于16.667ms(尽管不那么频繁)。
我应该说,当onDrawFrame报告从上次迭代开始花费的时间超过16.667ms时,几乎总是伴随着FPS的下降(下降到58或59),但并非总是如此,有时FPS保持不变。相反,有时,当FPS下降时,将在最后一次迭代完成的16.667ms内调用onDrawFrame。
所以......
我正在尝试修复游戏循环并消除这些“结结巴结”-需要注意的其他事项:
我显然误会了一些东西,因此朝正确方向的插入将不胜感激。
OnDrawFrame
@Override
public void onDrawFrame(GL10 gl) {
startTime = System.nanoTime();
fps++;
totalTime = System.nanoTime() - timeSinceLastCalled;
if (totalTime > 16667000) {
Log.v("Logging","Time between onDrawFrame calls: " + (totalTime /(double)1000000));
}
//Grab time
newTime = System.currentTimeMillis() * 0.001;
frameTime = newTime - currentTime; //Time the last frame took
if (frameTime > 0.25)
frameTime = 0.25;
currentTime = newTime;
accumulator += frameTime;
while (accumulator >= dt){
saveGameState();
updateLogic();
accumulator -= dt;
}
interpolation = (float) (accumulator / dt);
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
render(interpolation);
if (startTime > lastSecond + 1000000000) {
lastSecond = startTime;
Log.v("Logging","fps: "+fps);
fps=0;
}
endTime = startTime;
timeSinceLastCalled = System.nanoTime();
}
上面的这个游戏循环就是这个出色的article的特色。
最佳答案
一些想法:
System.currentTimeMillis()
计时。它基于挂钟,可以通过网络进行更新。使用基于单调时钟的System.nanoTime()
。 请参阅Grafika's“记录GL应用程序” Activity ,以获取一个简单的GLES应用程序的示例,该应用程序会丢帧,但会调整动画以使其很少引起注意。
关于android - Android:了解OnDrawFrame,FPS和VSync(OpenGL ES 2.0),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38512936/