将对象坐标转换为屏幕坐标,Android OpenGL ES

时间:2015-10-06 13:39:24

标签: android opengl-es coordinates

我尝试使用OpenGL ES为Android创建应用,但我在处理触摸输入方面遇到了问题。

我创建了一个CubeGLRenderer类,它生成了一个Cube。 CubeGLRenderer负责投影和视图矩阵,Cube负责其模型矩阵。立方体沿正X轴移动,Y和Z没有移动。

CubeGLRenderer每帧更新视图矩阵,以便与立方体一起移动,使立方体在屏幕上看起来是静止的:

Matrix.setLookAtM(mViewMatrix, 0, 0.0f, cubePos.y, -10.0f, 0.0f, cubePos.y, 0.0f, 0.0f, 1.0f, 0.0f);

每当屏幕尺寸改变时(即,当设备的方向改变时),计算投影矩阵。然后将这两个矩阵多处理并传递给Cube.draw(),在那里它应用其模型矩阵并将其自身呈现为屏幕。

到目前为止,这么好。让我们继续讨论这个问题。

我想触摸屏幕并计算从立方体屏幕坐标中心到我触摸屏幕点的角度。

我认为我只是使用GLU.gluProject()完成此操作,但我要么没有正确使用它,要么根本就没理解它。

这是我用来从立方体的世界坐标计算屏幕坐标的代码:

public boolean onTouchEvent(MotionEvent e) {
    Vec3 cubePos = cube.getPos();
    float[] modelMatrix = cube.getModelMatrix();
    float[] modelViewMatrix = new float[16];
    Matrix.multiplyMM(modelViewMatrix, 0, mViewMatrix, 0, modelMatrix, 0);
    int[] view = {0, 0, width, height};
    float[] screenCoordinates = new float[3];
    GLU.gluProject(cubePos.x, cubePos.y, cubePos.z, modelViewMatrix, 0, mProjectionMatrix, 0, view, 0, screenCoordinates, 0);


    switch (e.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.d("CUBEAPP", "screenX: " + String.valueOf(screenCoordinates[0]));
            break;
    }

    return true;
}

我做错了什么?

1 个答案:

答案 0 :(得分:0)

您在用于渲染立方体的顶点着色器中执行的相同计算应该用于将立方体中心转换为屏幕空间。

通常,您将通过modelViewProjection矩阵将立方体的每个顶点相乘,然后将其发送到片段着色器。 您应该使用在顶点着色器中使用的完全相同的矩阵,并将多维数据集的中心与其相乘。 但是,将4x4矩阵与Vec4顶点(x,y,z,1)相乘会得到Vec4结果(x2,y2,z2,w)。 为了获得屏幕空间坐标,你需要将x2和y2除以w! 用w除以w后,你的xy坐标应该在[-1..1] x [-1..1]范围内。

为了获得精确的像素,您需要将x2 / w和y2 / w标准化为[0..1],然后将其乘以屏幕分辨率的宽度和高度。

希望这有帮助。