[带有2D手指手势的Android OpenGL ES转换

问题描述 投票:0回答:1

是否有用于进行2D转换的示例代码:使用手指手势为2D OpenGL ES场景旋转,缩放,平移。类似于this,但适用于Android而非iPhone?我到处搜索,但找不到任何有用的源代码。

android opengl-es transformation
1个回答
0
投票

一种方法是从手指的像素坐标中获取OpenGL的坐标。在SurfaceView类中定义事件处理方法:

public class SurfaceView extends GLSurfaceView implements GestureDetector.OnGestureListener, 
        GestureDetector.OnDoubleTapListener {
    private GestureDetectorCompat detector;
    private CoordinatesOpenGL coordinatesOpenGL;
    private volatile float xPress; 
    private volatile float yPress;

    public SurfaceView() {
        ...
        detector = new GestureDetectorCompat(context, this);
        detector.setOnDoubleTapListener(this);
        coordinatesOpenGL = new CoordinatesOpenGL();
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent e) {
        return mDetector.onTouchEvent(e) || super.onTouchEvent(e);
    }
    // event handling methods
    @Override public boolean onDown(MotionEvent event) { ... return true; }
    @Override public boolean onSingleTapConfirmed(MotionEvent event) { ... return true; }
    @Override public boolean onDoubleTap(MotionEvent event) { ... return true; }
    @Override public boolean onDoubleTapEvent(MotionEvent event) { ... return true; }
    @Override public void onShowPress(MotionEvent motionEvent) { ... return true; }
    @Override public boolean onSingleTapUp(MotionEvent motionEvent) { ... return true; }
    @Override public boolean onScroll(MotionEvent event1, MotionEvent event2,
                      float distanceX, float distanceY) { ... return true; }
    @Override public void onLongPress(MotionEvent motionEvent) {}
    @Override public boolean onFling(MotionEvent motionEvent1, MotionEvent motionEvent2, 
                      float v1, float v2) { ... return true; }

然后,在其中一种方法中,计算OpenGL的坐标:

@Override
public boolean onDown(MotionEvent event) {
    coordinatesOpenGL.fromDisplay(renderer.getWidthDisplay(),
        renderer.getHeightDisplay(),
        event.getX(), event.getY());
    xPress = coordinatesOpenGL.getXGL(); // get OpenGL coordinates
    yPress = coordinatesOpenGL.getYGL();
    renderer.setPassXY(xPress, yPress);
    return true;
}

为了计算OpenGL坐标,我写了一个方法(Kotlin),但也许还有其他标准函数:

fun fromDisplay(displayWidth: Int, displayHeight: Int,
                    displayX: Float, displayY: Float) {
    val offsetX: Float // offset X-axis (pixels)
    val offsetY: Float // offset Y-axis (pixels)

    val centerX = displayWidth / 2 // x of screen center (pixels)
    val centerY = displayHeight / 2 // y of screen center (pixels)

    if (displayX <= centerX && displayY >= centerY) { // left-down quarter
        offsetX = (centerX - displayX)
        offsetY = (displayY - centerY)
        xGL = -(offsetX / centerX)
        yGL = -(offsetY / centerY)
    } else if (displayX <= centerX && displayY <= centerY) { // left-up quarter
        offsetX = (centerX - displayX)
        offsetY = (centerY - displayY)
        xGL = -(offsetX / centerX)
        yGL = offsetY / centerY
    } else if (displayX >= centerX && displayY <= centerY) { // rigth-up quarter
        offsetX = (displayX - centerX)
        offsetY = (centerY - displayY)
        xGL = offsetX / centerX
        yGL = offsetY / centerY
    } else if (displayX > centerX && displayY > centerY) { // rigth-down quarter
        offsetX = (displayX - centerX)
        offsetY = (displayY - centerY)
        xGL = offsetX / centerX
        yGL = -(offsetY / centerY)
    }
}

在Render类中,使用OpenGL坐标移动对象:

...
Matrix.translateM(modelMatrix, 0, x, y, z)
...
public void setPassXY(Float passX, Float passY) {
    ...
    x = xPass * aspect * factor; // or yPass * aspect - depending on orientation
    y = yPass * factor;
    ...
} 
© www.soinside.com 2019 - 2024. All rights reserved.