OpenGL ES(MonoTouch) - gluUnProject的手动实现

时间:2011-04-17 23:48:36

标签: ios opengl-es xamarin.ios opentk

我已经在其他地方看到了同样的主题,但在大多数情况下,解决方案提供商正在处理2D(正交)投影,因此它们会掩盖Z值。我的世界有以下特点:

  1. 透视投影
  2. 相机的“向上”向量始终为{0,1,0}
  3. 相机的Z坐标始终为正(朝向Z = 0)
  4. 我试图确定命中点的平面是Z = 0
  5. 我正在使用gluUnProject的端口,虽然我认为我的端口实现是合理的,但肯定会出现问题。然而,我希望向社区提出的问题是,如果我的算法在下面看起来是正确的。我在winZ = 0(近平面)和winZ = 1(远平面)确定世界坐标。然后我确定来自这两个点的光线,对其进行归一化,并确定该光线的Z坐标为0的值(在什么时刻它与Z = 0平面相交,这就是我所追求的) 。然而,问题是,当我点击原点(0,0,0)附近时,这是有效的,但是一旦我开始点击原点,错误就会增加(例如,如果正确的世界坐标应该 be 50,0,0它们实际上是85,0,0,基于下面的计算。

    如果下面的步骤合理,那么我可以开始研究我的gluUnProject实现。

    public override void TouchesBegan (NSSet touches, UIEvent evt)
    {
        base.TouchesBegan (touches, evt);
        var pt = (touches.AnyObject as UITouch).LocationInView(this);
    
        int[] viewport = new int[4];
        float[] proj = new float[16];
        float[] model = new float[16];
    
        GL.GetInteger(All.Viewport, viewport);
        GL.GetFloat(All.ProjectionMatrix, proj);
        GL.GetFloat(All.ModelviewMatrix, model);
    
        float[] near = new float[3];
        float[] far = new float[3];
    
        Utils.gluUnProjectf(pt.X, viewport[3] - pt.Y, 0f, model, proj, viewport, out near);
        Utils.gluUnProjectf(pt.X, viewport[3] - pt.Y, 1f, model, proj, viewport, out far);
    
        Vector rayDirection = new Vector(far[0] - near[0], far[1] - near[1], far[2] - near[2]);
        rayDirection.Normalize();
    
        float t = (0 - near[2]) / rayDirection.dZ;
    
        Vertex end = new Vertex();
        end.X = near[0] + rayDirection.dX * t;
        end.Y = near[1] + rayDirection.dY * t;
        end.Z = 0;
    }
    

1 个答案:

答案 0 :(得分:0)

我使用完整版OpenGL(使用gluUnProject完成)实现了相同的算法,并获得了所需的结果。算法很合理,我对gluUnProject的实现不是。