2012-05-26 5 views
4

표준 버텍스, 색상 및 포인트 버퍼를 사용하여 3D 객체를 표시하는이 테스트 앱으로 모든 작업을 수행했습니다. 내가 할 수있는GLSurfaceView를 사용한 드래그 및 확대/축소 이벤트의 이해 및 적용

..

  • 가 GL10에게
  • 모두를 사용하여 OpenGL을 ES 1.0 개체를 렌더링 터치 이벤트와 개체를 회전은

지금 내가 할 수있게하려면 좋은 작품 "핀치"동작을 위해 두 손가락을 사용하여 확대 및 축소합니다. 좋은 튜토리얼과 샘플 코드를 찾았지만 대부분 ImageViews 용입니다. 나는 여전히 Android의 새로운 버전이며 GLSurfaceView에서이 줌 기능을 사용하는 방법을 완전히 이해하지 못했습니다.

다음은 활동 등급에 대한 코드입니다. 첫 번째 터치 처리기는 ImageView 용 자습서에서 찾은 확대/축소 이벤트 용입니다 (이 컨버팅은 쉬운 전환이라고 생각했기 때문에 사용했습니다). 두 번째 핸들러는 잘 작동하는 rotation 이벤트 용입니다.

미리 감사 드리며이 게시물이 다른 사람들에게 동일한 문제로 도움이되기를 바랍니다. 필요한 수정 사항이나 추가 사항은 대기 상태가됩니다.

// Activity for rendering 3D object openGL ES 1.0 
public class GL_ExampleActivity extends Activity 
{ 
     private GLSurfaceView surface; 

     @Override 
     public void onCreate(Bundle savedInstanceState) 
     { 
      super.onCreate(savedInstanceState); 

      surface = new GL_ExampleSurfaceView(this); 
      setContentView(surface); 
     } 

     @Override 
     protected void onPause() 
     { 
      // TODO Auto-generated method stub 
      super.onPause(); 
      surface.onPause(); 
     } 

     @Override 
     protected void onResume() 
     { 
      // TODO Auto-generated method stub 
      super.onResume(); 
      surface.onResume(); 
     } 
} 

class GL_ExampleSurfaceView extends GLSurfaceView 
{ 
     private static final String TAG = "Touch"; 

     Matrix matrix_new = new Matrix(); 
     Matrix last_matrix = new Matrix(); 

     static final int NONE = 0; 
     static final int DRAG = 1; 
     static final int ZOOM = 2; 
     int mode = NONE; 

     PointF start = new PointF(); 
     PointF mid = new PointF(); 
     float oldDist = 1f; 


     private final float SCALE_FACTOR = 180.0f/320; 
     private GLRenderer renderer; 
     private float previous_x; 
     private float previous_y; 

     public GL_ExampleSurfaceView(Context context) 
     { 
      super(context); 

      renderer = new GLRenderer(); 
      setRenderer(renderer); 

      setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 
     } 

     @Override 
     public boolean onTouchEvent(MotionEvent e) 
     { 
      // handler for drag and zoom events 
      switch (e.getAction() & MotionEvent.ACTION_MASK) 
      { 
       case MotionEvent.ACTION_DOWN: 
        last_matrix.set(matrix_new); 
        start.set(e.getX(), e.getY()); 
        Log.d(TAG, "mode=DRAG"); 
        mode = DRAG; 
        //requestRender(); 
        break; 
       case MotionEvent.ACTION_POINTER_DOWN: 
        oldDist = finger_distance(e); 
        Log.d(TAG, "oldDist=" + oldDist); 
        if (oldDist > 10f) 
        { 
         last_matrix.set(matrix_new); 
         finger_distance_midpoint(mid, e); 
         mode = ZOOM; 
         Log.d(TAG, "mode=ZOOM"); 
        } 
        //requestRender(); 
        break; 
       case MotionEvent.ACTION_UP: 
       case MotionEvent.ACTION_POINTER_UP: 
        mode = NONE; 
        Log.d(TAG, "mode=NONE"); 
        //requestRender(); 
        break; 
       case MotionEvent.ACTION_MOVE: 
        if (mode == DRAG) 
        { 
          matrix_new.set(last_matrix); 
          matrix_new.postTranslate(e.getX() - start.x, e.getY() - start.y); 
        } 
        else if (mode == ZOOM) 
        { 
          float newDist = finger_distance(e); 
          Log.d(TAG, "newDist=" + newDist); 
          if (newDist > 10f) 
          { 
           matrix_new.set(last_matrix); 
           float scale = newDist/oldDist; 
           matrix_new.postScale(scale, scale, mid.x, mid.y); 
          } 
        } 
        //requestRender(); 
        break; 
      } 
      //view.setImageMatrix(matrix_new); 



      // handler for rotation event, y and x axis 
      float x = e.getX(); 
      float y = e.getY(); 

      switch (e.getAction()) 
      { 
       case MotionEvent.ACTION_MOVE: 

       float dx = x - previous_x; 
       float dy = y - previous_y; 

       if (y > getHeight()/2) 
       { 
        dx = dx * -1 ; 
       } 

       if (x < getWidth()/2) 
       { 
        dy = dy * -1 ; 
       } 
       renderer.angle_x += dx * SCALE_FACTOR; 
       renderer.angle_y += dy * SCALE_FACTOR; 
       requestRender(); 
      } 
      previous_x = x; 
      previous_y = y; 
      return true; 
     } 


     private float finger_distance(MotionEvent e) 
     { 
      float x = e.getX(0) - e.getX(1); 
      float y = e.getY(0) - e.getY(1); 
      return FloatMath.sqrt(x * x + y * y); 
     } 

     private void finger_distance_midpoint(PointF point, MotionEvent e) 
     { 
      float x = e.getX(0) + e.getX(1); 
      float y = e.getY(0) + e.getY(1); 
      point.set(x/2, y/2); 
     } 

} 

다시 한 번 감사드립니다 ...

+0

에 대한 자세한 정보를 찾을 수 있습니다
(당신이 대신 glOrthof을 사용하는 것입니다 직교 행렬을 사용하는 경우, 주) 이봐, 당신은 어떤 솔루션을 가지고 이에? – kendrelaxman

답변

2

이 접근하는 두 가지 확실한 방법이 있습니다. 개별 객체의 크기를 늘리려는 경우 객체를 그리는 경우 glScalef를 사용할 수 있습니다. scalef를 사용하는 것은 쉽고 비교적 간단하지만 사용자가 요구하는 것이 아닙니다.

다른 해결책은 원하는 효과를 낼 수있는 스케일링 계수를 투영 행렬에 적용하는 것입니다. 이것을 달성하기 위해, 그리기 전에 투영 행렬의 왼쪽, 오른쪽, 위쪽 및 아래쪽 거리에 그렇게 스케일을 곱하면됩니다.

gl.glFrustumf (너비/2 * 줌, 너비/2 * 줌, 높이/2 * 줌, 높이/2 * 줌, 1, -1); 당신이 관심이 있다면

것은, 당신이 투영 행렬 here