Android Gameloop (openGL ES 2.0) 的问题
Posted
技术标签:
【中文标题】Android Gameloop (openGL ES 2.0) 的问题【英文标题】:Problems with Android Gameloop (openGL ES 2.0) 【发布时间】:2014-05-20 17:03:04 【问题描述】:概述
在我的游戏循环中出现很多不连贯的动画问题。我正在运行循环 onDrawFrame 如您所见,如果循环时间过长,我的循环允许跳帧(我使用的是固定时间增量,60fps 的时间“切片”为 16.666666 毫秒)。
我已经确认跳帧时会发生卡顿。
出现跳帧时,如何防止动画出现断断续续的情况?如果它绝对必须跳帧(我承认在某些设备上有时会发生这种情况),我该如何减轻这种断断续续的情况?
自上次调用以来,onDrawFrame(GL10 gl) 似乎在 24 毫秒内被调用。在我的 Google Nexus 10 平板电脑上,我的实际渲染可能需要 5 到 14 毫秒,而我的游戏更新只需要 0 到 4 毫秒,所以大部分时间它应该很适合 16.6666 时间片。但是,当我从 onDrawFrame 中删除所有内容时,它的调用间隔似乎在 16 到 25 毫秒之间。 (大多数时候,它超过 16 毫秒),因此,它跳过了很多帧——即使没有调用渲染或更新!!
这似乎违背了以 60FPS 运行的设备的全部意义 - 这个 VSync 是这样做的吗?超过 16 毫秒有什么意义?
我尝试过的事情
好的,我尝试生成一个单独的线程来运行我的更新(同样,将它们限制为每秒 60 次)。我仍然遇到问题。
我也尝试过插值,但这又没有任何区别。 (我将发布一个单独的问题,看看我是否正确)。
我真的很挣扎,所以我希望有人能提供帮助!
代码
float interpolation;
long nextGameTick = System.currentTimeMillis();
//loop counter
int loops;
//This is the amount of frames that we allow our app to skip before logic updating is affected (generally shouldn't happen)
final int maxFrameskip = 5;
//Game updates per second
final int ticksPerSecond = 60;
//Amount of time each update should take
final int skipTicks = (1000 / ticksPerSecond);
public void onDrawFrame(GL10 gl)
//Set/Re-set loop back to 0 to start counting again
loops=0;
while(System.currentTimeMillis() > nextGameTick && loops < maxFrameskip)
SceneManager.getInstance().getCurrentScene().updateLogic();
nextGameTick+=skipTicks;
timeCorrection += (1000d/ticksPerSecond) % 1;
nextGameTick+=timeCorrection;
timeCorrection %=1;
loops++;
tics++;
interpolation = (float)(System.currentTimeMillis() + skipTicks - nextGameTick)
/ (float)skipTicks;
render(interpolation);
应用插值
render(float interpolation)
//This example shows interpolation for X axis only. Y position (spriteScreenY is assumed to be valid)
interpolatedPosX = spriteGridX+(SpriteXVelocity*dt)*interpolation;
spriteScreenPosX = interpolationPosX * screenWidth;
drawSprite(spriteScreenX, spriteScreenY);
【问题讨论】:
你在你的游戏循环中分配了内存吗(请记住,使用 for-each 语法遍历集合会分配一个迭代器)? GC 可能会导致卡顿。检查“D/dalvikvm GC_CONCURRENT freed”的 logcat 调试消息,它会显示它暂停了多长时间。 嗨@thanks for the comment - 在我的循环中没有发生分配 - 这是我检查的第一件事,所以我很早就排除了 - 干杯! @Zippy 你解决了这个问题吗。我也有同样的问题 嗨@Sunny,不幸的是,我还没有解决它。我已经尝试了所有方法,但在跳过帧时仍然有断断续续的动画。现在,我只是忍受它,但需要在某个时候重新访问它。如果您遇到任何建议,很想听听他们的意见!! :-( 【参考方案1】:尝试使用 RENDERMODE_WHEN_DIRTY。这意味着不再使用 onDrawFrame,而是在游戏循环中使用 requestRender()。
【讨论】:
以上是关于Android Gameloop (openGL ES 2.0) 的问题的主要内容,如果未能解决你的问题,请参考以下文章