2012-01-17 11 views
0

私はopenGLを使って正方形をレンダリングする簡単なアンドロイドアプリケーションを作った。正方形は指で動かすことができます。それは正常に動作しますが、周りの四角形を動かすと、特に円形の動きをするときにかなりの入力遅れを感じることができます。この遅れを減らすかマスクするためのトリックはありますか?ここで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; 
     } 
    } 
} 
+0

コードがかなり速いはずです。遅れを引き起こす可能性があるのは、同期化された翻訳(またはonTouchEventですが、この場合は遅れを生じさせてはならず、一種の吃音を引き起こす可能性があります)だけです。同期を取り除き、問題が改善しているかどうかを確認してください。 – Jave

+0

同期ブロックを削除しても遅延は減少しませんでした。また、レンダリングモードをCONTINUOUSからWHEN_DIRTYに設定しようとしましたが、どちらも役に立ちませんでした。 – gq3

+0

レンダリングが遅いデバイスかもしれませんか? – Jave

答えて

1

は、あなたのUIスレッドとあなたのレンダリングスレッドがCPU時間のために戦っていると思います。 )onSurfaceCreated(に次の行を追加してみてください:

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

レンダラの優先順位を下げるとモーションイベントは、もう少し迅速に処理されるようにします。違いを生むようだ。

FWIW GLSurfaceViewのデザインは嫌いですが、Handler.postDelayed()を使用して、設定されたフレームレート(通常は50)を目標にして、各フレームを20ms間隔で描画するようにスケジュールします。

+0

スレッドの優先順位を変更しても目に見える違いはありません。しかし、OpenGLレンダリングにGLSurfaceView以外のものをどのように使うことができますか? – gq3

+0

ICSを実行しているNexus Sでは、間違いなく違いがあるようです。 Re GLSurfaceViewは、ソースコードを見てください。 SurfaceViewを拡張し、EGLセットアップを行いますが、専用のレンダリングスレッドを使用しないバリアントを作成できます。 –

+0

私はそれを調べます、おそらく私はNDKを使用してより良いパフォーマンスを得ることができます。 – gq3