Отзывчивость Android OpenGL - PullRequest
       0

Отзывчивость Android OpenGL

1 голос
/ 17 января 2012

Я сделал простое приложение для Android, которое визуализирует квадрат с помощью openGL. Квадрат можно перемещать с помощью пальца. Он работает нормально, но при перемещении квадрата вы можете почувствовать значительную задержку ввода, особенно при выполнении круговых движений. Есть ли уловки, чтобы уменьшить или замаскировать это отставание?

Вот код:

public class InputTestActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new InputTestView(this));
    }

    public class InputTestView extends GLSurfaceView {
        private InputTestRenderer renderer;

        private float prevX;
        private float prevY;

        public InputTestView(Context context) {
            super(context);
            renderer = new InputTestRenderer();
            setRenderer(renderer);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();
            switch(event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                renderer.moveEye(prevX - x, prevY -y);
            case MotionEvent.ACTION_DOWN:
                prevX = x;
                prevY = y;
                break;
            }
            return true;
        }   
    }

    public class InputTestRenderer implements Renderer {
        private final float[] verts = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f };
        private final int nrOfVerts = verts.length / 3;
        private FloatBuffer vertBuf;

        private float eyeX;
        private float eyeY;

        public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

            gl.glColor4f(1, 0, 0, 1);

            ByteBuffer byteBuffer = ByteBuffer.allocateDirect(verts.length * Float.SIZE / 8);
            byteBuffer.order(ByteOrder.nativeOrder());
            vertBuf = byteBuffer.asFloatBuffer();
            vertBuf.put(verts);
            vertBuf.position(0);
        }

        public void onSurfaceChanged(GL10 gl, int width, int height) {
            gl.glViewport(0, 0, width, height);

            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glOrthof(-width / 2, width / 2, height / 2, -height / 2, 1, 100);
            gl.glMatrixMode(GL10.GL_MODELVIEW);
        }

        public void onDrawFrame(GL10 gl) {
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

            gl.glLoadIdentity();
            synchronized (this) {
                gl.glTranslatef(-eyeX, -eyeY, -10);
            }
            gl.glScalef(200, 200, 1);

            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuf);
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, nrOfVerts);
        }

        public synchronized void moveEye(float deltaX, float deltaY) {
            this.eyeX += deltaX;
            this.eyeY += deltaY;
        }
    }
}

1 Ответ

1 голос
/ 17 января 2012

Подозреваю, что ваш поток пользовательского интерфейса и ваш поток рендеринга борются за процессорное время. Попробуйте добавить эту строку в onSurfaceCreated ():

Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

Уменьшение приоритета рендерера обеспечивает более быструю обработку событий движения. Кажется, что имеет значение.

FWIW Мне не нравится дизайн GLSurfaceView, и я предпочитаю стремиться к установленной частоте кадров, обычно 50, используя Handler.postDelayed (), чтобы планировать каждый кадр, который будет рисоваться с интервалами 20 мс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...