How to implement the iphone style multitouch zoomIn zoomOut to a polygon on a GLSurfaceView?
i have an application that shows a simple square polygon represented on a GLSurfaceView. Actually i can do zoomIn and zoomOut with two buttons.
But now i want to implemente the iphone multitouch style zoomIn and zoomOut. It means that when the user presses with two fingers the screen and move one finger into another, the user is doing zoomOut, and when the user separates the fingers makes zoomIn.
How can i implement this with Android, openglES, and GLsurfaceView?
the class:
public class MySurfaceView extends GLSurfaceView implements Renderer {
private Context context;
private Square square;
/* Rotation values */
private float xrot; //X Rotation
private float yrot; //Y Rotation
/* Rotation speed values */
private float xspeed; //X Rotation Speed ( NEW )
private float yspeed; //Y Rotation Speed ( NEW )
private float z = -5.0f; //Depth Into The Screen ( NEW )
/*
开发者_运维问答 * These variables store the previous X and Y
* values as well as a fix touch scale factor.
* These are necessary for the rotation transformation
* added to this lesson, based on the screen touches. ( NEW )
*/
private float oldX;
private float oldY;
private final float TOUCH_SCALE = 0.2f; //Proved to be good for normal rotation ( NEW )
public MySurfaceView(Context context) {
super(context);
this.context = context;
setEGLConfigChooser(8, 8, 8, 8, 16, 0); //fondo transparente
getHolder().setFormat(PixelFormat.TRANSLUCENT); //fondo transparente
//Set this as Renderer
this.setRenderer(this);
//Request focus, otherwise buttons won't react
this.requestFocus();
this.setFocusableInTouchMode(true);
square = new Square();
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER); //Disable dithering ( NEW )
gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
gl.glClearColor(0,0,0,0); //fondo transparente
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
//Load the texture for the cube once during Surface creation
square.loadGLTexture(gl, this.context);
}
public void onDrawFrame(GL10 gl) {
//Clear Screen And Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity(); //Reset The Current Modelview Matrix
//Drawing
gl.glTranslatef(0.0f, 0.0f, z); //Move z units into the screen
gl.glScalef(0.8f, 0.8f, 0.8f); //Scale the Cube to 80 percent, otherwise it would be too large for the screen
//Rotate around the axis based on the rotation matrix (rotation, x, y, z)
gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f); //X
gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f); //Y
square.draw(gl); //Draw the Cube
//Change rotation factors
xrot += xspeed;
yrot += yspeed;
}
/**
* If the surface changes, reset the view
*/
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) { //Prevent A Divide By Zero By
height = 1; //Making Height Equal One
}
gl.glViewport(0, 0, width, height); //Reset The Current Viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Projection Matrix
gl.glLoadIdentity(); //Reset The Projection Matrix
//Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
}
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
//If a touch is moved on the screen
if(event.getAction() == MotionEvent.ACTION_MOVE) {
//Calculate the change
float dx = x - oldX;
float dy = y - oldY;
//Define an upper area of 10% on the screen
//int upperArea = this.getHeight() / 10;
//Zoom in/out if the touch move has been made in the upper
//if(y < upperArea) {
//z -= dx * TOUCH_SCALE / 2;
//Rotate around the axis otherwise
//} else {
xrot += dy * TOUCH_SCALE;
yrot += dx * TOUCH_SCALE;
//}
//A press on the screen
} else if(event.getAction() == MotionEvent.ACTION_UP) {
//Define an upper area of 10% to define a lower area
//int upperArea = this.getHeight() / 10;
//int lowerArea = this.getHeight() - upperArea;
//Change the light setting if the lower area has been pressed
//if(y > lowerArea) { }
}
//Remember the values
oldX = x;
oldY = y;
//We handled the event
return true;
}
public void zoomIn(){ z=z+0.2f; }
public void zoomOut(){ z=z-0.2f; }
}
done using this method: http://www.zdnet.com/blog/burnette/how-to-use-multi-touch-in-android-2-part-6-implementing-the-pinch-zoom-gesture/1847
精彩评论