OpenGL ES: Zoom und pan springen immer wieder zur Ausgangsposition zurück

Tschulz

Mitglied
Hallo,
ich möchte eine Zoom- und Pan-Funktion in OpenGL implementieren. Das ganze funktioniert auch soweit. Meine SurfaceView class enthält einen TouchHandler und berechnet den Wert um den die ModelMatrix skaliert werden soll. Doch jedes Mal wenn ich erneut zoomen möchte springt das Objekt zuerst auf die Ausgangsposition zurück bevor gezoomt wird. Das gleiche gilt für die Pan-Funktion.

Kann mir jemand sagen, was ich ändern muss, damit von der aktuellen Position aus gezoomt wird?
Vielen Dank!

Hier ist mein Code-Snippet aus der Renderer-Klasse:

Code:
public class renderer implements GLSurfaceView.Renderer {

	public float scale;

	public renderer() {


		Squares = new Objects();
	}

	public void onDrawFrame(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
		gl.glScalef(scale, scale, 1); // Zoom
		gl.glRotatef(-15.0f, 1.0f, 0.0f, 0.0f); // Rotieren im Perspektive zu erzeugen


		Squares.draw(gl);

	}
 
Die Version mit pan ist

Code:
public class renderer implements GLSurfaceView.Renderer {

	public float scale;
	public float panX;
	public float panY;
	

	public renderer() {
		Squares = new Objects();
	}

	public void onDrawFrame(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
		gl.glScalef(scale, scale, 1); // Zoom
		gl.glRotatef(-15.0f, 1.0f, 0.0f, 0.0f); // Rotieren im Perspektive zu erzeugen

		gl.glTranslatef(panX, 0, panY); // pan

		Squares.draw(gl);


scale und pan werden hier verändert:

Code:
package Jules.pack.age;

import android.content.Context;
import android.graphics.PointF;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;

public class SurfaceView extends GLSurfaceView {
	private renderer mRenderer;

	// Remember some things for zooming

	float oldDist;
	float oldX;
	float oldY;
	float newX;
	float newY ;

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

	public SurfaceView(Context context) {
		super(context);
	}

	public void showRenderer(renderer renderer) {
		this.mRenderer = renderer;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {

		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:
			oldX = event.getX();
			oldY = event.getY();
			mode = DRAG;
			break;
		case MotionEvent.ACTION_POINTER_DOWN:
			oldDist = spacing(event);
			if (oldDist > 10f) {
				mode = ZOOM;
			}
			break;
		case MotionEvent.ACTION_UP:

		case MotionEvent.ACTION_POINTER_UP:
			mode = NONE;

			break;
		case MotionEvent.ACTION_MOVE:
			if (mode == DRAG) {
				newX = event.getX();
				newY = event.getY();

				float dx = (newX - oldX);
				float dy = (newY - oldY);

				mRenderer.panX = dx;
				mRenderer.panY = -dy;

			} else if (mode == ZOOM) {
				float newDist = spacing(event);

				 if (newDist > 10f) {
				float scale = newDist / oldDist;

				mRenderer.scale = scale;
				 }
			}
			break;
		}
		return true;
	}

	// Abstand zwischen zwei Fingern
	private float spacing(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);
	}


}
 
Ja, die Werte werden ja jedes mal neu gesetzt... GANZ grob sowas wie
Java:
// Weg
//				mRenderer.panX =dx;
//				mRenderer.panY = -dy;
// Hin
				mRenderer.panX +=dx;
				mRenderer.panY += -dy;

//Weg
//				mRenderer.scale = scale;
				mRenderer.scale *= scale;

Über Details und Faktoren muss man sich dann noch genauer Gedanken machen.
 

Zurück
Oben