在调用update时,Android OpenGL上一帧会在拆分时刻重新出现

在调用update时,Android OpenGL上一帧会在拆分时刻重新出现,android,opengl-es-2.0,Android,Opengl Es 2.0,我刚刚开始在我的小游戏中使用OpenGL ES 2 for android,在每一帧上重新绘制屏幕时遇到了一个问题 我在渲染器的onDrawFrame上设置了一个循环,只是一个简单的[updateGameLogic->drawGame]或Thread.sleep循环,基于上次drawGame调用的时间间隔 目前,updateGameLogic方法只需将相机转换为游戏2d的+VEX方向 在drawGame调用中,我首先用GLES20.glClearGLES20.GL_COLOR_BUFFER_BI

我刚刚开始在我的小游戏中使用OpenGL ES 2 for android,在每一帧上重新绘制屏幕时遇到了一个问题

我在渲染器的onDrawFrame上设置了一个循环,只是一个简单的[updateGameLogic->drawGame]或Thread.sleep循环,基于上次drawGame调用的时间间隔

目前,updateGameLogic方法只需将相机转换为游戏2d的+VEX方向

在drawGame调用中,我首先用GLES20.glClearGLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT清除屏幕。然后我有3个glBindTexture和GLDrawerElements调用,用于绘制具有不同纹理图谱的3类对象

问题来了,在屏幕上绘制的每一帧之间,出现了前一帧的闪烁,这是不希望出现的,使游戏看起来头晕。确切地说,假设游戏即将从第2帧中画出第3帧,就在第2帧消失和第3帧出现之前,有一个分裂的时刻显示第1帧


我认为这可能是由于系统缓冲GLSURFACHEVIEW的方式,所以我尝试在绘制之前调用多个glClear,但一切都保持不变。如果有人能解释/解决这个问题,以及我做错了什么,我将不胜感激,谢谢。基本上,第2到第4段都是我的代码,所以我没有发布它,除非评论中的澄清要求,听起来你的代码中有这样的内容:

public void onDrawFrame(GL10 gl) {
    long currentTime = SystemClock.elapsedRealtime();
    long deltaTime = currentTime - mLastFrameTime;
    if (deltaTime < 33) {
        Thread.sleep(33 - deltaTime);
        return;
    }

    mLastFrameTime = currentTime;

    updateGameLogic(deltaTime);
    drawGame();
}
请注意,虽然仍然存在人为延迟,但代码中不再有提前返回


对于将重画速度限制在30 fps,这种想法可能有更强大的变化。在SO或internet上的其他部分进行搜索,应该会发现以前的讨论。

请求澄清:您说您在onDrawFrame中设置了一个循环。在这个方法中你真的有一个循环吗?还是每次调用该方法时只画一帧?谢谢您的关注。我的措辞不好,方法中没有实际的循环,循环存在的意义是onDrawFrame将被系统重复调用。我的onDrawFrame以IF语句开始,这样它就会进入Thread.sleep,如果从上次渲染开始的时间小于33毫秒并返回void,则会调用sleep。我一直等到Android再次调用onDrawFrame,才根据上面的IF再次实际绘制。可爱的是,我基本上移植了以前在SurfaceView上使用的代码,它使用了我不知道GLSurfaceView的渲染器不喜欢的机制。经过一些调整后,它现在工作得又好又平滑。我很惊讶,尽管我在网上读到的各种教程中都没有提到这种行为。
public void onDrawFrame(GL10 gl) {
    long currentTime = SystemClock.elapsedRealtime();
    long deltaTime = currentTime - mLastFrameTime;
    if (deltaTime < 33) {
        Thread.sleep(33 - deltaTime);
        currentTime = SystemClock.elapsedRealtime();
        deltaTime = currentTime - mLastFrameTime;
    }

    mLastFrameTime = currentTime;

    updateGameLogic(deltaTime);
    drawGame();
}