5

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);

    }

    }
Aida E
  • 1,108
  • 2
  • 22
  • 40

1 Answers1

4

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.

Jave
  • 31,598
  • 14
  • 77
  • 90
  • do you have any example of doing this ? I don't know how to set up on touch method for doing this and most of the examples of zooming on internet use scaling not camera – Aida E May 04 '12 at 13:33
  • basically the `zoom` value is a scaling factor, although it changes the 'camera' rather than modifying the scene. If you have a method that can calculate a value from the pinch you can insert that. Otherwise I can post a snippet when I get home. – Jave May 04 '12 at 13:36
  • If you give me an example of doing this (setting up zoom with changing frustum parameters ) on a triangle or whatever shape I would be so grateful. – Aida E May 04 '12 at 13:40
  • @matarsak what do you mean "it does not work"? You get any error messages? Or does nothing happen? As I said, you will probably have to run the `glFrustumf()` method on your gl-thread and not the one that takes the input. – Jave May 06 '12 at 08:27
  • I add that zoom method in rendrer at the end .it gives me error with gl.glfrustum because of this zoom method but in onSurfaceChanged method there is no error with the same thing ! I dont know how to add this zoom method there... – Aida E May 06 '12 at 15:58
  • @Jave what is that pMatrix argument for frustumM? Just by reading your code i can only see zooming in and out but no translation. Pinch zoom must have translation. – Martin Berger Apr 12 '13 at 09:46
  • @MartinBerger: `pMatrix` is the float array that will contain a projection matrix after the frustum-method has competed. The question only refers to zooming, so that is what I have answered. If you want translation you could just translate your view-matrix in the onTouch/MOVE event. – Jave Apr 12 '13 at 11:36
  • @Jave yes, he only asks about zooming, not zooming to arbitrary point, my mistake. Thank you. – Martin Berger Apr 12 '13 at 12:14