简体   繁体   English

框架在GLSurfaceView上出现乱序

[英]Frames appearing out of order on GLSurfaceView

I'm writing an Android app using OpenGL ES and encountered this problem in the Nexus 5 emulator that comes with Android Studio. 我正在使用OpenGL ES编写一个Android应用,并且在Android Studio随附的Nexus 5仿真器中遇到此问题。 I have reduced my code to this small app, which simply draws a box going back and forth: 我已将代码简化为这个小应用程序,该应用程序简单地绘制了一个来回的框:

package net.jesbus.stuttertest;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class MainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        // Create GLSurfaceView
        GLSurfaceView glsv = new GLSurfaceView(this);
        glsv.setEGLConfigChooser(8, 8, 8, 8, 16, 0);

        // Create GLSurfaceView.Renderer
        glsv.setRenderer(new GLSurfaceView.Renderer()
        {
            float step = 0;
            boolean direction = false;
            ShortBuffer iBuff;
            FloatBuffer vBuff;
            @Override
            public void onSurfaceCreated(GL10 gl, EGLConfig config)
            {
                // Generate vertices index buffer
                short[] pIndex = {0, 1, 2, 3};
                ByteBuffer pbBuff = ByteBuffer.allocateDirect(pIndex.length * 2);
                pbBuff.order(ByteOrder.nativeOrder());
                iBuff = pbBuff.asShortBuffer();
                iBuff.put(pIndex);
                iBuff.position(0);

                // Generate vertices buffer
                float[] vs = new float[]
                        {
                                -1, +1, 0,
                                +1, +1, 0,
                                -1, -1, 0,
                                +1, -1, 0,
                        };
                ByteBuffer bBuff = ByteBuffer.allocateDirect(vs.length * 4);
                bBuff.order(ByteOrder.nativeOrder());
                vBuff = bBuff.asFloatBuffer();
                vBuff.put(vs);
                vBuff.position(0);
            }

            @Override
            public void onDrawFrame(final GL10 gl)
            {
                // Animation calculation
                step += direction ? 0.02f : -0.02f;
                if (step > 1) direction = false;
                else if (step < 0) direction = true;

                // Set background color
                gl.glClearColor(0.7f, 0.7f, 1, 1);

                // Clear screen
                gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

                // Set matrix to correct location
                gl.glLoadIdentity();
                gl.glTranslatef(-1 + step * 2, 0, 0);
                gl.glScalef(0.25f, 0.4f, 1);

                // Draw box
                gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
                gl.glFrontFace(GL10.GL_CW);
                gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuff);
                gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4, GL10.GL_UNSIGNED_SHORT, iBuff);
                gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
            }

            @Override
            public void onSurfaceChanged(GL10 gl, int width, int height)
            {
            }
        });
        setContentView(glsv);
    }
}

I looked at it frame by frame, and it seems that instead of showing the next frame, it shows the previous frame, and then skips the frame it was supposed to show and continues: 我逐帧看了看它,它似乎没有显示下一帧,而是显示了前一帧,然后跳过了原本应该显示的帧并继续:

帧顺序错误

The circles represent frames produced in onDrawFrame, and the arrows represent the flow of time. 圆圈表示在onDrawFrame中生成的帧,箭头表示时间流。

Video showing the problem 显示问题的视频

I don't exactly know how threading is used OpenGL, but try this: 我不完全知道OpenGL如何使用线程,但是请尝试以下操作:

    // Animation calculation
    synchronized (this) {
        step += direction ? 0.02f : -0.02f;
        if (step > 1) direction = false;
        else if (step < 0) direction = true;
    }

or make the whole onDrawFrame() method synchronized if the compiler consents and OpenGL doesn't lock up... 或者如果编译器同意并且OpenGL没有锁定,则使整个onDrawFrame()方法同步...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM