1. 程式人生 > >OpenGL ES2.0實現手指滑動平移、雙指縮放Android

OpenGL ES2.0實現手指滑動平移、雙指縮放Android

主要是實現了手指在螢幕上滑動實現平移,兩個手指進行縮放。主要是這部分矩陣還挺麻煩的。

效果圖如下所示:

核心部分程式碼如下

觸控事件處理:

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        //ACTION_DOWN不return true,就無觸發後面的各個事件
        if (motionEvent != null) {
            final float normalizedX =toOpenGLCoord(view,motionEvent.getX(),true);
            final float normalizedY =toOpenGLCoord(view,motionEvent.getY(),false);
            switch (motionEvent.getActionMasked()){
                case MotionEvent.ACTION_DOWN:
                    X=normalizedX;
                    Y=normalizedY;
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
                    isZooming=true;
                    float x1=toOpenGLCoord(view,motionEvent.getX(1),true);
                    float y1=toOpenGLCoord(view,motionEvent.getY(1),false);
                    dis_start=computeDis(normalizedX,x1,normalizedY,y1);

                    break;
                case MotionEvent.ACTION_MOVE:
                    if(isZooming){
                        float x2=toOpenGLCoord(view,motionEvent.getX(1),true);
                        float y2=toOpenGLCoord(view,motionEvent.getY(1),false);
                        double dis=computeDis(normalizedX,x2,normalizedY,y2);
                        double scale=dis/dis_start;
                        zoom((float) scale);
                        dis_start=dis;
                    }else {
                        move(normalizedX - X, normalizedY - Y);
                        X = normalizedX;
                        Y = normalizedY;
                    }
                    break;
                case MotionEvent.ACTION_POINTER_UP:
                    isZooming=false;
                    X = normalizedX;
                    Y = normalizedY;
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                default:break;
            }
            return true;
        }
        return false;
    }
  /**
     * 螢幕座標系點轉OpenGL座標系
     * @return
     */
    private static float toOpenGLCoord(View view,float value,boolean isWidth){
        if(isWidth){
            return (value / (float) view.getWidth()) * 2 - 1;
        }else {
            return -((value / (float) view.getHeight()) * 2 - 1);
        }
    }

    /**
     * 計算兩個點之間的距離
     * @param x1
     * @param x2
     * @param y1
     * @param y2
     * @return
     */
    private static double computeDis(float x1,float x2,float y1,float y2){
        return sqrt(pow((x2-x1),2)+pow((y2-y1),2));
    }

render部分矩陣處理:

    private final float[] translateMatrix = new float[16];//平移矩陣
    private final float[] zoomMatrix = new float[16];//縮放矩陣

    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        //初始化平移矩陣和縮放矩陣為單位矩陣
        setIdentityM(translateMatrix,0);//建立單位矩陣
        setIdentityM(zoomMatrix,0);//建立單位矩陣
    }
  @Override
    public void onDrawFrame(GL10 gl10) {
        glClear(GL_COLOR_BUFFER_BIT);

        //平移支援
        //兩個矩陣相乘
        float[] temp = new float[16];
        multiplyMM(temp, 0, projectionMatrix, 0, translateMatrix, 0);
        float[] temp2 = new float[16];
        multiplyMM(temp2, 0, zoomMatrix, 0, temp, 0);

        Log.e(TAG,"重新繪製");
        for(int i=0;i<brushes.size();i++){
            Brush brush=brushes.get(i);
            brush.draw(temp2);
        }
    }
 /**
     * 改變繪圖座標系的偏移值
     * @param dx
     * @param dy
     */
    public void move(float dx, float dy){
        //根據當前縮放的比例調節平移引數
        translateM(translateMatrix,0,dx/zoomMatrix[0],dy/zoomMatrix[0],0);//新增平移引數
    }

    /**
     * 縮放檢視
     * @param scale 縮放比例
     */
    public void zoom(float scale){
        scaleM(zoomMatrix,0,scale,scale,0);//新增縮放參數
    }