Android OpenGL ES在触摸屏上添加对象

Android OpenGL ES在触摸屏上添加对象,android,opengl-es,touch,coordinates,Android,Opengl Es,Touch,Coordinates,我正在构建一个小型Android应用程序,它将在用户触摸屏上添加一个立方体。z深度始终为-10,屏幕始终处于横向模式。这个问题似乎被问了很多次,但我无法让它运行,请原谅我,因为我是opengl的新手。 我对gluUnproject使用的屏幕坐标/窗口坐标/对象坐标感到非常困惑。据我所知,当用户触摸屏幕时,我们甚至可以从运动中得到x和y。窗口坐标是加载标识时的坐标,对象坐标是变换标识矩阵以获得对象坐标时的坐标。是这样吗 这是我的代码,矩阵堆栈来自android api示例。请指出我做错了什么 图

我正在构建一个小型Android应用程序,它将在用户触摸屏上添加一个立方体。z深度始终为-10,屏幕始终处于横向模式。这个问题似乎被问了很多次,但我无法让它运行,请原谅我,因为我是opengl的新手。 我对gluUnproject使用的屏幕坐标/窗口坐标/对象坐标感到非常困惑。据我所知,当用户触摸屏幕时,我们甚至可以从运动中得到x和y。窗口坐标是加载标识时的坐标,对象坐标是变换标识矩阵以获得对象坐标时的坐标。是这样吗

这是我的代码,矩阵堆栈来自android api示例。请指出我做错了什么


图纸部分:

public void draw(GL10 gl) {
    for (GLObject glObject : list) {
        if (glObject != null) {
            gl.glLoadIdentity();
            glObject.draw(gl);
        }
    }
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();
    if (isTouching) {
        boolean addObject = false;
        for (GLObject glObject : list) {
            addObject = glObject.checkTouch(gl, x, y);
        }
        if (!addObject) {
            i++;
            Log.d("i", i + "");
            addGLObject(gl);
        }
        isTouching = false;
    }
}

下面是添加对象的代码

private void getMatrix(GL10 gl, int mode, float[] mat) {
    GLView.matrixTrackingGL.glMatrixMode(mode);
    GLView.matrixTrackingGL.getMatrix(mat, 0);
}
public void addGLObject(GL10 gl) {
    float[] XY = getWorldCoordinate(gl, x, y);

    if (XY != null) {
//          XY[0] = (float) (x - Main.SCREEN_WIDTH / 2) / 10;
//
//          XY[1] = (float) (Main.SCREEN_HEIGHT / 2 - y) / 10;

        GLObject glObject = new GLObject(colors, XY[0], XY[1]);
        Log.d("Object position", "X: " + XY[0] + " Y: " + XY[1]);
        list.add(glObject);
    }
}
private float[] getWorldCoordinate(GL10 gl, int x, int y) {
    float[] modelMatrix = new float[16];
    float[] projMatrix = new float[16];
    int[] viewport = {0, 0, Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT};


    getMatrix(gl, GL10.GL_MODELVIEW, modelMatrix);
    getMatrix(gl, GL10.GL_PROJECTION, projMatrix);

    float[] output = new float[4];
    GLU.gluUnProject(x, viewport[1] + viewport[3] - y, -10, modelMatrix, 0, projMatrix, 0, viewport, 0, output, 0);
    return new float[] {output[0]/output[3], output[1]/output[3]};
}

}


昂德劳:

public void onDrawFrame(GL10 gl) {
        // TODO Auto-generated method stub
        // Clears the screen and depth buffer.
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | // OpenGL docs.
                GL10.GL_DEPTH_BUFFER_BIT);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        // Reset the projection matrix
        gl.glLoadIdentity();
        GLU.gluPerspective(gl, 90.0f, Main.SCREEN_WIDTH/Main.SCREEN_HEIGHT, 3.0f, 100.0f); 
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        GLU.gluLookAt(gl, 4.0f, 2.0f, 1.0f, 
                0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);    
        // draw object
        glObjectManager.draw(gl);
    }

它与横向模式无关,问题是你在z轴上将立方体平移-10。尝试将值设置为-100,所有立方体都将位于中心。然后尝试将0作为z值(x,y,0)。立方体将离屏幕中心更远,更接近您期望的位置


查看透视投影的示例。当立方体位于z=0时,这就是图像中的内容。但当z=-10时,它更靠近屏幕中心(X)且更小,因为它沿着蓝线一直延伸到地平线。

它与横向模式无关,问题是在z轴上将立方体平移-10。尝试将值设置为-100,所有立方体都将位于中心。然后尝试将0作为z值(x,y,0)。立方体将离屏幕中心更远,更接近您期望的位置


查看透视投影的示例。当立方体位于z=0时,这就是图像中的内容。但当z=-10时,它更靠近屏幕中心(X)且更小,因为它沿着蓝线一直延伸到地平线。

您遇到的具体问题是什么,您能提供GLObject的实现吗?@NickLH我的问题是当我触摸屏幕时,对象被添加,但没有添加到我触摸的点。他们总是加得很近,但我不知道我哪里做错了,因为我不擅长数学,也不熟悉OpenGl。GLObject I的代码如上所述添加。感谢您的帮助:)它添加到错误的位置可能是因为您的z坐标为-10。我不知道,因为您没有发布这部分代码,但是如果您使用的是投影矩阵(我假设您是),那么由于透视投影,您的框将不会显示在指定的点上。请尝试使用正交投影或打印x和y坐标,以查看您单击的位置和对象创建的位置是否正确。@NickLH我添加了onDraw方法,更详细地说,我的屏幕始终处于横向模式。当我绘制一个对象时,我将其转换为(x,y,-10)(GLObject draw函数中的代码),下一个对象将加载标识矩阵并继续绘制。它与横向模式无关,问题是您在z轴上将立方体转换为-10。尝试将值设置为-100,所有立方体都将位于中心。然后尝试将0作为z值(x,y,0)。立方体将离屏幕中心更远,更接近您期望的位置。您遇到的具体问题是什么,您能提供GLObject的实现吗?@NickLH我的问题是当我触摸屏幕时,对象被添加,但没有添加到我触摸的点。他们总是加得很近,但我不知道我哪里做错了,因为我不擅长数学,也不熟悉OpenGl。GLObject I的代码如上所述添加。感谢您的帮助:)它添加到错误的位置可能是因为您的z坐标为-10。我不知道,因为您没有发布这部分代码,但是如果您使用的是投影矩阵(我假设您是),那么由于透视投影,您的框将不会显示在指定的点上。请尝试使用正交投影或打印x和y坐标,以查看您单击的位置和对象创建的位置是否正确。@NickLH我添加了onDraw方法,更详细地说,我的屏幕始终处于横向模式。当我绘制一个对象时,我将其转换为(x,y,-10)(GLObject draw函数中的代码),下一个对象将加载标识矩阵并继续绘制。它与横向模式无关,问题是您在z轴上将立方体转换为-10。尝试将值设置为-100,所有立方体都将位于中心。然后尝试将0作为z值(x,y,0)。立方体将离屏幕中心更远,更接近您期望的位置。我发现问题在于GlunProject。如果我用1(不是-10)替换z,我接收的输出数组将类似于(0.3…,0.2…,1,0.01…),如果我得到输出[0]/(输出[3]*10),它将返回正确的点。因为这很荒谬,我会读更多的。谢谢你的帮助,威尔马克你的回答是:我发现问题出在GlunProject上。如果我用1(不是-10)替换z,我接收的输出数组将类似于(0.3…,0.2…,1,0.01…),如果我得到输出[0]/(输出[3]*10),它将返回正确的点。因为这很荒谬,我会读更多的。谢谢你的帮助,我会记下你的答案
public void onDrawFrame(GL10 gl) {
        // TODO Auto-generated method stub
        // Clears the screen and depth buffer.
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | // OpenGL docs.
                GL10.GL_DEPTH_BUFFER_BIT);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        // Reset the projection matrix
        gl.glLoadIdentity();
        GLU.gluPerspective(gl, 90.0f, Main.SCREEN_WIDTH/Main.SCREEN_HEIGHT, 3.0f, 100.0f); 
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        GLU.gluLookAt(gl, 4.0f, 2.0f, 1.0f, 
                0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);    
        // draw object
        glObjectManager.draw(gl);
    }