OpenGL ES如何应用来自android.graphics.Matrix的转换 [英] OpenGL ES how to apply transformations from android.graphics.Matrix

查看:403
本文介绍了OpenGL ES如何应用来自android.graphics.Matrix的转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个3x3的 android.graphics.Matrix ,我想将所有转换仅应用于4x4的OpenGL矩阵以进行2D转换.到目前为止,我已经设法应用旋转和缩放比例,我使用的是来自Android团队的示例 HERE 渲染三角形.我使用了用于根据用户针对比例移动翻译转换而做出的手指手势生成android.graphics.Matrix.

I have a 3x3 android.graphics.Matrix, and i want to apply all transformation to a 4x4 OpenGL Matrix for 2D transformations only. So far I have manage to apply rotation and scaling I am using the example from the android team HERE to render a triangle. I used this class for generating the android.graphics.Matrix, from finger gestures made by the user for scale, move and translate transformations.

之后,我将 MatrixGestureDetector .在MyGLSurfaceView类中:

After that I attach the MatrixGestureDetector on the onTouchEvent from the View. In the MyGLSurfaceView class:

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

Then I used it to convert the android.graphics.Matrix to a OpenGL Matrix in the onDrawFrame method in MyGLRenderer class

    ...
    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更改为:

To apply the translation I have to add the m[2] and m[5] from the android.graphics.Matrix values and change the openGLMatrix to:

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]范围内的坐标形成的,请看下面的图片:

Now the problem is that the OpenGL viewbox size is formed by coordinates in range [-1,1], look at the image below:

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

But the translation X and Y values from the android.graphics.Matrix are not in that range, to do that I changed it to:

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转换?

Now translation work, but scale and rotation are not done on the pivot point(center point of rotation between the two fingers). How to apply all the transformation and is there a example code for 2D transformations for finger gestures that I can find anywhere?

推荐答案

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

Well, I figure out that there is miscalculations in the conversion from Graphic coordinate system to a OpenGL coordinate system for the translation. Here is the code for getting the accurate translation in a OpenGL coordinate system, set as separate functions:

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矩阵,并使用手指手势的应用转换,这里是类

I have also updated the whole finger gesture transformation class, for generating the OpenGL matrix, with the applied transformations from the finger gestures here is the class OpenGLFingerGestureTransformations.

要获取OpenGL矩阵,请先创建自己的 OpenGLMatrixGestureDetector 对象,方法与创建MatrixGestureDetector的方法相同:

To get the OpenGL matrix first create your own OpenGLMatrixGestureDetector object, using the same way as creating 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 .
这是最终结果:

I have uploaded the full source code HERE.
Here is the final result:

这篇关于OpenGL ES如何应用来自android.graphics.Matrix的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆