【问题标题】:OpenGL ES how to apply transformations from android.graphics.MatrixOpenGL ES 如何应用来自 android.graphics.Matrix 的转换
【发布时间】:2020-04-24 17:28:43
【问题描述】:

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

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

class MyGLSurfaceView : GLSurfaceView {

    ...
    private val matrixGestureDetector = MatrixGestureDetector()

    override fun onTouchEvent(e: MotionEvent): Boolean {

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

然后我用它在 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]范围内的坐标形成的,看下图:

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】:

    好吧,我发现在从图形坐标系到 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 矩阵,首先创建您自己的 OpenGLMatrixGestureDetector 对象,使用与创建 MatrixGestureDetector 相同的方法:

    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
    这是最终结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-19
      • 1970-01-01
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多