0

我正在尝试创建一个简单的 Android OpenGL 2.0 游戏来弄湿我的脚。我参考了有关 OpenGL 的 Androids 教程并启动并运行它,将我的方块移动到我想要的位置,现在我正在尝试通过触摸翻译它。

我读过我必须取消投影当前的正方形......但不理解这一点。如果对在广场上执行翻译有任何帮助,下面是我的代码...

 private float mPreviousY;

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        // MotionEvent reports input details from the touch screen
        // and other input controls. In this case, you are only
        // interested in events where the touch position changed.
    float y = e.getY();

    switch (e.getAction()) {
        case MotionEvent.ACTION_MOVE:

            float dy = y - mPreviousY;

            // reverse direction of rotation to left of the mid-line
            if (y < getHeight() / 2) {
              dy = dy * -1 ;
            }

            mRenderer.mOffSet += dy;
            requestRender();
    }

    mPreviousY = y;
    return true;
}

我的 onDrawFrame:

    @Override
public void onDrawFrame(GL10 unused) {

    // Draw background color
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    // Set the camera position (View matrix)
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -50, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

    Matrix.translateM(mModleViewProjMatrix, 0, 0, mOffSet, 0);

    // Calculate the projection and view transformation
    Matrix.multiplyMM( mModleViewProjMatrix, 0, mProjMatrix, 0, mViewMatrix, 0);

    // Draw square
    mPaddle.draw(mModleViewProjMatrix);
}
4

1 回答 1

1

非投影意味着反转顶点在变换时所经历的过程。正向变换是

v_eye = Modelview · v

v_clip = Projection · v_eye

v_ndc = v_clip / v_clip.w

现在你要做的就是扭转这个过程。我建议你看看 Mesa 的 GLU 函数 gluUnProject 的源代码,可以在这里找到http://cgit.freedesktop.org/mesa/glu/tree/src/libutil/project.c

更新

取消投影本质上是在逆转这个过程。

我们看一下 Mesa 的 GLU gluUnProject 代码:

GLint GLAPIENTRY
gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
        const GLdouble modelMatrix[16], 
        const GLdouble projMatrix[16],
                const GLint viewport[4],
            GLdouble *objx, GLdouble *objy, GLdouble *objz)
{
    double finalMatrix[16];
    double in[4];
    double out[4];

首先评估复合变换Projection · Modelview……</p>

    __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);

……倒置,即倒置;

    if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);

    in[0]=winx;
    in[1]=winy;
    in[2]=winz;
    in[3]=1.0;

然后将窗口/视口坐标映射回 NDC 坐标

    /* Map x and y from window coordinates */
    in[0] = (in[0] - viewport[0]) / viewport[2];
    in[1] = (in[1] - viewport[1]) / viewport[3];

    /* Map to range -1 to 1 */
    in[0] = in[0] * 2 - 1;
    in[1] = in[1] * 2 - 1;
    in[2] = in[2] * 2 - 1;

并乘以复合投影模型视图的逆

    __gluMultMatrixVecd(finalMatrix, in, out);

最后检查,所谓的同质分量是非零的

    if (out[3] == 0.0) return(GL_FALSE);

并且同质划分倒置。

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

导致投影过程之前的原始顶点位置

    *objx = out[0];
    *objy = out[1];
    *objz = out[2];
    return(GL_TRUE);
}
于 2012-12-23T23:19:48.323 回答