简体   繁体   中英

Android OpenGL ES rotate 3D object with touch event

This is an Android application. I want to rotate a sphere with touch event using Matrix in OpenGLES 2.0. However the angle is not right. It seems like the rotate is not stable. I want to rotate only x when I touch horizontally, and rotate only y when I touch vertically. But in fact, when I touch horizontally it rotate x and y, so did when I touch vertically... Something wrong with the calculation of rotate anglex and angley or the Matrix set up? Here is the touch event:

public boolean onTouchEvent(MotionEvent e) {
    float x = e.getX();
    float y = e.getY();

    switch (e.getAction()) {
        case MotionEvent.ACTION_MOVE:

            float dx = x - mPreviousX;
            float dy = y - mPreviousY;

            mRenderer.setAngleX(mRenderer.getAngleX() + (dx * TOUCH_SCALE_FACTOR));
            mRenderer.setAngleY(mRenderer.getAngleY() - (dy * TOUCH_SCALE_FACTOR));
            requestRender();
    }
        mPreviousX = x;
        mPreviousY = y;
        return true;
    }

This is the Matrix set up:

public void onDrawFrame(GL10 unused) {
    // Draw background color
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    //set up the matrix
    float [] mTempMatrix = new float[16];
    Matrix.setIdentityM(mModelMatrix, 0); // initialize to model matrix
    Matrix.setIdentityM(mTranslateMatrix,0);
    Matrix.translateM(mTranslateMatrix, 0, 0.0f, 0.0f, 0.0f);
    mTempMatrix = mModelMatrix.clone();
    Matrix.multiplyMM(mModelMatrix,0,mTempMatrix,0,mTranslateMatrix,0);

    Matrix.setIdentityM(mRotationMatrix,0);
    Matrix.rotateM(mRotationMatrix, 0, mAngleX, 0,1,0);
    Matrix.rotateM(mRotationMatrix, 0, mAngleY, 1,0,0);
    mTempMatrix = mModelMatrix.clone();
    Matrix.multiplyMM(mModelMatrix,0,mTempMatrix,0,mRotationMatrix,0);

    Matrix.setIdentityM(mScaleMatrix,0);
    Matrix.scaleM(mScaleMatrix,0, 1f, 1f, 1f);
    mTempMatrix = mModelMatrix.clone();
    Matrix.multiplyMM(mModelMatrix,0,mTempMatrix,0,mScaleMatrix,0);
    Matrix.setLookAtM(mViewMatrix, 0,
            mLocation.x,mLocation.y,mLocation.z,
            mTarget.x,mTarget.y,mTarget.z,
            mUp.x,mUp.y,mUp.z);//camera
    mTempMatrix = mViewMatrix.clone();

    Matrix.multiplyMM(mViewMatrix, 0, mTempMatrix,0,mModelMatrix,0);
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

    mSphere.draw(mMVPMatrix);
}

It seems to me that since you use

mRenderer.setAngleX(mRenderer.getAngleX() + (dx * TOUCH_SCALE_FACTOR));

Even if dx is 0, any previous angle (through mRenderer.getAngleX() ) will be re-applied in the next iteration. Let dx alone modify mAngleX instead (and do the same for mAngleY of course):

mRenderer.mAngleX += dx * TOUCH_SCALE_FACTOR;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM