2012-01-17 3 views
0

OpenGL을 사용하여 사각형을 렌더링하는 간단한 Android 애플리케이션을 만들었습니다. 손가락을 사용하여 사각형을 움직일 수 있습니다. 잘 작동하지만 사각형을 움직이면 상당한 지연을 느낄 수 있습니다. 특히 원형 동작을 할 때 특히 그렇습니다. 이 지연을 줄이거 나 마스킹하는 트릭이 있습니까?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

동기화 된 블록을 제거해도 지연이 줄어들지 않았습니다. 렌더링 모드를 CONENNUOUS에서 WHEN_DIRTY로 설정하려고했지만 그 역시 도움이되지 않았습니다. – gq3

+0

아마도 렌더링이 느린 장치일까요? – Jave

답변

1

용의자 당신의 UI 스레드와 렌더링 스레드가 CPU 시간을 싸우고있다 :

여기에 코드입니다. onSurfaceCreated()이 줄을 추가하십시오 :

렌더러의 우선 순위를 감소
Thread.currentThread().setPriority(Thread.MIN_PRIORITY); 

모션 이벤트가 신속하게 좀 더 처리 할 수 ​​있도록 최선을 다하고 있습니다. 차이를 만드는 것처럼 보입니다.

FWIW 나는 GLSurfaceView의 디자인을 싫어하고 Handler.postDelayed()를 사용하여 20ms 간격으로 그려지는 프레임을 예약하기 위해 일반적으로 50 프레임짜리 프레임을 목표로합니다.

+0

스레드 우선 순위를 변경해도 눈에 띄는 차이는 없습니다. 하지만 GLSurfaceView 이외의 다른 것들을 OpenGL 렌더링에 정확히 사용하려면 어떻게 설명 할 수 있습니까? – gq3

+0

ICS를 실행하는 Nexus S에서는 확실히 차이를 만드는 것처럼 보입니다. Re GLSurfaceView, 소스 코드보기. SurfaceView를 확장하고 EGL 설치를 수행하지만 전용 렌더링 스레드를 사용하지 않는 변형을 작성할 수 있습니다. –

+0

NDK를 사용하면 더 나은 성능을 얻을 수 있습니다. – gq3