Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android pinch/zoom and glfrustum

I draw several 2D shapes using OpenGL and now I want to add the pinch/zoom. My view is perspective (top view). I assumed that it's 3D with z axis = 0.

Now, how should I change glfrustum and add on a touch method in my activity so that I could be able to pinch/zoom?

gl.glFrustumf(-ratio, ratio, -1, 1, 1, 25);

I think it should be something like

gl.glFrustumf(-ratio, ratio, -1, 1, 1*zoom, 25*zoom);

but how should the touch method be written to change this zoom parameter for doing two finger zoom?

the problem is rendrer right now , I add zoom method at the end , but in zoom method it gives me error with gl.glfrustum while on onsurfacechanged it does not give me error with the same thing ! how could I fix that ?

public class GLrenderer implements Renderer {
    public GLqueue tri;
    public GLrenderer() {
        tri = new GLqueue();


    }


    public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) {
        // TODO Auto-generated method stub
        gl.glDisable(GL10.GL_DITHER);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
        gl.glClearColor(.0f, .0f, .0f, 0f);
        gl.glClearDepthf(1f);
    }


    public void onDrawFrame(GL10 gl) {
        // TODO Auto-generated method stub
        gl.glDisable(GL10.GL_DITHER);
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_COLOR_BUFFER_BIT);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        GLU.gluLookAt(gl, 0, 0, -5, 0, 0, 0, 0, 2, 0);

        //gl.glRotatef(1, 1, 0, 0);
    //  gl.glRotatef(10, 0, 0, 1);
        tri.draw(gl);

    }

    public void onSurfaceChanged(GL10 gl, int width, int height ) {
        // TODO Auto-generated method stub
        gl.glViewport(0, 0, width, height);
        float ratio = (float) width / height;
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();

        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 25);
    }

    public static void zoom(float d2) {
        // TODO Auto-generated method stub
          int zoom = (int) (zoom*d2);

                gl.glFrustumf(-ratio, ratio, -1, 1, 1*zoom, 25*zoom);

    }

    }
like image 379
Aida E Avatar asked Oct 07 '22 22:10

Aida E


1 Answers

If you have some float value that determines your zoom, you can use this:

glFrustum(left*zoom, right*zoom, bottom*zoom, top*zoom, near, far);

Here is an example:

excerpt from the OnTouchListener

public boolean onTouch(View v, MotionEvent event) {
    switch(event.getAction()){
    case MotionEvent.ACTION_DOWN:
        pointers = 1;
        return true;
    case MotionEvent.ACTION_POINTER_2_DOWN:
        pointers = 2;
        distance = fingerDist(event);
        return true;
    case MotionEvent.ACTION_MOVE:
        if( pointers == 2 ){
            float newDist = fingerDist(event);
            float d = distance/newDist;
            renderer.zoom(d);
            distance = newDist;
        }
        return true;
    default:
        return false;
    }

    }

protected final float fingerDist(MotionEvent event){
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return FloatMath.sqrt(x * x + y * y);
}

From the renderer:

public final void zoom(float mult){
    zoom *= mult;
    Matrix.frustumM(
            pMatrix, 0, 
            zoom*left, zoom*right, zoom*bottom, zoom*top, 
            near, far);
}

Note that this code is written for gles 2.0 rather then 1.0, so instead of calling Matrix.frustumM() you would call gl.glFrustumf(). You might possibly have to post this operation to your gl-thread for it to work properly.

like image 103
Jave Avatar answered Oct 12 '22 12:10

Jave