2012-01-17 39 views
0

我做了一個簡單的android應用程序,它使用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 2012-01-17 12:06:16

+0

刪除同步塊沒有減少延遲,我也嘗試將渲染模式從連續設置爲WHEN_DIRTY,但這也沒有幫助。 – gq3 2012-01-17 13:03:38

+0

也許這是渲染緩慢的設備? – Jave 2012-01-17 13:17:15

回答

1

懷疑你的UI線程和您的渲染線程都在爭取的CPU時間。嘗試添加該行onSurfaceCreated():

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

減少渲染器的優先確保移動事件得到及時處理多一點。似乎有所作爲。

FWIW我不喜歡GLSurfaceView的設計,並且傾向於使用Handler.postDelayed()來設置幀速率(通常爲50),以每20ms間隔繪製每個幀。

+0

更改線程優先級並沒有明顯的區別。但是你能解釋一下,我可以如何使用GLSurfaceView以外的任何東西來進行OpenGL渲染? – gq3 2012-01-18 11:19:27

+0

在運行ICS的Nexus S上,它絕對看起來有所作爲。重新GLSurfaceView,看它的源代碼。您可以創建一個變體,它也擴展了SurfaceView並執行EGL設置,但不使用專用渲染線程。 – 2012-01-18 11:33:19

+0

我會研究它,也許我可以使用NDK獲得更好的性能。 – gq3 2012-01-20 13:08:38