首页 > 解决方案 > 在 Android 上使用 GLES20 获得正确的非投影触摸坐标的问题

问题描述

我正在尝试使用 OpenGL 作为我的基础为 Android 开发一个简单的游戏应用程序。到目前为止,我有一个非常基本的设置,其中包含一些形状和一个实例化正方形的对象类。可以通过触摸和拖动来平移相机,并使用两根手指进行缩放。我一直在尝试查看许多关于如何使用 gluUnProject 获取触摸坐标并将它们转换为世界坐标的教程。到目前为止,我得到了非常复杂的结果,例如当触摸到达屏幕边缘时坐标不准确。这是我的触摸检测代码的基础供参考:

public int selectEntity(float x, float y)
{
    //x and y parameters are the raw touch coordinates
    for(GameObj entity: entities)
    {
        System.out.println("Coordinates of touch before matrix transformation: X: " + x + ", Y: " + y);
        y = mView[3] - y; //flipping y to match y origin
        System.out.println("Coordinates of touch after flipping Y: X: " + x + ", Y: " + y);

        //I have used two matrices to hold unprojected transforms:
        //nearPos is calculated using nearPlane value of 1
        //farPos is calculate using farPlane value of 10
        float[] nearPos = new float[4];
        float[] farPos = new float[4];

        //I pass the MVPMatrix as the 4th parameter currently, although
        //everywhere else that I've seen, the modelView matrix is used,
        //but I have no idea how that is acquired. I have tried using
        //GLES11 to fetch it but that gave me no results. I have also
        //tried passing the View Matrix, but that gave worse results.
        //mView holds [0,0,width,height] of screen
        boolean unprojectedNear = (GLU.gluUnProject(x, y, 1,
                mMVPMatrix, 0, mProjectionMatrix, 0,
                mView, 0, nearPos, 0) == GLES20.GL_TRUE);
        boolean unprojectedFar = (GLU.gluUnProject(x, y, 10,
                mMVPMatrix, 0, mProjectionMatrix, 0,
                mView, 0, farPos, 0) == GLES20.GL_TRUE);
        if (unprojectedNear && unprojectedFar)
        {
            System.out.println("Converted point coords at farpos: X: " + farPos[0]/farPos[3] + ", Y: " + farPos[1]/farPos[3] + ", Z(?): " + farPos[2]/farPos[3] );
            System.out.println("Converted point coords at nearpos: X: " + nearPos[0]/nearPos[3] + ", Y: " + nearPos[1]/nearPos[3] + ", Z(?): " + nearPos[2]/nearPos[3] );

            //dividing by the w component
            nearPos[0] /= nearPos[3];
            nearPos[1] /= nearPos[3];
            nearPos[2] /= nearPos[3];
            nearPos[3] /= nearPos[3];

            farPos[0] /= farPos[3];
            farPos[1] /= farPos[3];
            farPos[2] /= farPos[3];
            farPos[3] /= farPos[3];

            //It is to my belief that the correct (x,y) world coordinates should be contained in either
            //(nearPos[0],nearPos[1]), or in (farPos[0],farPos[1])
        }

        //I have tried to use farPos instead of nearPos here with inconcusive results
        if(entity.touched(nearPos[0], nearPos[1]))
        {
            System.out.println("I AM AN OBJECT AND I HAVE BEEN TOUCHED");
        }
    }
    return -1;
}

我不太熟悉 OpenGL 的复杂性,但我认为我的问题可能在于无法正确导入 modelView 矩阵。这个概念本身仍然让我感到困惑,它只是对象模型与视图矩阵的乘积吗?传递视图矩阵还不够吗?另外,我打算制作 2D 游戏,所以在这种情况下,由于正交投影,我真的需要担心使用远近平面值吗?

如果我的任何其他代码有助于更好地理解这个问题,我很乐意提供。

谢谢你。

标签: javaandroidopengl-esglu

解决方案


推荐阅读