OpenGL ES如何应用来自android.graphics.Matrix的转换

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

我有一个3x3 android.graphics.Matrix,我只想将所有转换应用于4x4 OpenGL矩阵,仅用于2D转换。到目前为止,我已经设法应用旋转和缩放比例,我正在使用android团队HERE的示例渲染三角形。我使用此class从用户进行scalemovetranslate转换的手指手势生成android.graphics.Matrix。

此后,我从视图将MatrixGestureDetector附加到onTouchEvent上。在MyGLSurfaceView类中:

class MyGLSurfaceView : GLSurfaceView {

    ...
    private val matrixGestureDetector = MatrixGestureDetector()

    override fun onTouchEvent(e: MotionEvent): Boolean {

        matrixGestureDetector.onTouchEvent(e)
        requestRender()
        return true
    } 
}

然后,我使用它在Windows的onDrawFrame方法中将android.graphics.Matrix转换为OpenGL矩阵MyGLRenderer

    ...
    lateinit var matrixGestureDetector: MatrixGestureDetector

    override fun onDrawFrame(unused: GL10) {
            ...
             // get graphics matrix values
             val m = FloatArray(9)
             matrixGestureDetector.matrix.getValues(m)

             // set rotation and scaling from graphics matrix to form new 4x4 OpenGL matrix
             val openGLMatrix = floatArrayOf(
                    m[0], m[3], 0f, 0f,
                    m[1], m[4], 0f, 0f,
                    0f, 0f, 1f, 0f,
                    0f, 0f, 0f, 1f
             )
             Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, openGLMatrix, 0)

             // draw shape, where scaling and rotation work
             mTriangle.draw(scratch)
    }

要应用翻译,我必须从android.graphics.Matrix值中添加m [2]m [5]并将openGLMatrix更改为:

val openGLMatrix = floatArrayOf(
    m[0], m[3], 0f, 0f,
    m[1], m[4], 0f, 0f,
    0f, 0f, 1f, 0f,
    m[2], m[5], 0f, 1f
)

现在的问题是,OpenGL viewbox的大小是由[-1,1]范围内的坐标形成的,请看下面的图片:enter image description here

但是android.graphics.Matrix中的X和Y转换值不在该范围内,为此我将其更改为:

val scaleX: Float = m[android.graphics.Matrix.MSCALE_X]
val skewY: Float = m[android.graphics.Matrix.MSKEW_Y] 
val translateX = m[android.graphics.Matrix.MTRANS_X]
val translateY = m[android.graphics.Matrix.MTRANS_Y]
val ratio = width.toFloat() / height

val openGLMatrix = floatArrayOf(
    m[0], m[3], 0f, 0f,
    m[1], m[4], 0f, 0f,
    0f, 0f, 1f, 0f,
    -ratio * (translateX / width * 2), -(translateY / height * 2), 0f, 1f
)

现在进行平移工作,但是在枢轴点(两个手指之间的旋转中心点)上没有进行缩放和旋转。如何应用所有转换,是否有示例代码可以在任何地方找到手指手势的2D转换?

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

嗯,我发现从图形坐标系到OpenGL坐标系的转换转换中存在错误的计算。这是用于在OpenGL坐标系中获得准确平移的代码,设置为单独的函数:

fun normalizeTranslateX(x: Float): Float {

    val translateX = if (x < width / 2f) {
        -1f + (x / (width / 2f))
    } else {
         (x - (width / 2f)) / (width / 2f)
    }

    return -translateX * OpenGLRenderer.NEAR * ratio
}

fun normalizeTranslateY(y: Float): Float {

    val translateY = if (y < height / 2f) {
        1f - (y / (height / 2f))
    } else {
        -(y - (height / 2f)) / (height / 2f)
    }

    return translateY * OpenGLRenderer.NEAR
}

我还更新了整个手指手势转换类,以生成OpenGL矩阵,其中来自手指手势的应用转换为OpenGLFingerGestureTransformations类。

要首先获取OpenGL矩阵,请使用创建MatrixGestureDetector的相同方法创建您自己的OpenGLMatrixGestureDetector对象:>

class MyGLSurfaceView : GLSurfaceView {

    ...
    private val matrixGestureDetector = OpenGLMatrixGestureDetector()

    override fun onTouchEvent(e: MotionEvent): Boolean {

        matrixGestureDetector.onTouchEvent(e)
        requestRender()
        return true
    } 
}

然后在[[MyGLRenderer

类中,仅使用方法transform()生成矩阵。... lateinit var matrixGestureDetector: OpenGLMatrixGestureDetector private val transformedMatrixOpenGL: FloatArray = FloatArray(16) override fun onDrawFrame(unused: GL10) { ... // get OpenGL matrix with the applied transformations, from finger gestures matrixGestureDetector.transform(mMVPMatrix, transformedMatrixOpenGL) // draw shapes with apply transformations from finger gestures mTriangle.draw(transformedMatrixOpenGL) }
我已经上传了完整的源代码HERE。这是最终结果:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.