5

OpenGLを使用していくつかの 2D 形状を描画し、ピンチ/ズームを追加したいと考えています。私の視点はパースペクティブ(上面図)です。z 軸 = 0 の 3D だと仮定しました。

さて、glfrustum を変更してアクティビティに touch メソッドを追加し、ピンチ/ズームできるようにするにはどうすればよいでしょうか?

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

私はそれが次のようなものであるべきだと思います

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

しかし、このズーム パラメータを変更して 2 本指ズームを行うには、どのように touch メソッドを記述すればよいでしょうか。

問題はレンドラーです。最後にズームメソッドを追加しますが、ズームメソッドではgl.glfrustumでエラーが発生しますが、onsurfacechangedでは同じことでエラーは発生しません! どうすれば修正できますか?

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

    }

    }
4

1 に答える 1

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.

于 2012-05-04T13:30:07.757 に答える