代码之家  ›  专栏  ›  技术社区  ›  Tesserex

我的项目和非项目功能有什么问题?

  •  3
  • Tesserex  · 技术社区  · 14 年前

    我使用OpenTK在C中进行游戏,它不附带项目和未投影函数,它们在世界坐标和屏幕坐标之间转换。是的,但是他们被否决了,我不能让他们工作。我试过自己根据 opengl spec (请参见左侧菜单,Glupproject和Glunproject,以及在FF中查看,而不是在Chrome中查看)。看看那些公式,我正在试着匹配它们。我的功能根本不起作用,项目返回的点都在我屏幕的中心附近,并且非常靠近,即使我正在将我的世界点移动到各处。

    注意,opentk的math lib不包括将矩阵乘以向量的函数,所以我只是对结果向量中的每个条目进行矩阵行乘以向量点积(这是正确的,不是吗?)

        public static Vector3d Project(Vector4d point, Matrix4d projection, Matrix4d modelview, int[] view)
        {
            Matrix4d temp = Matrix4d.Mult(projection, modelview);
            // multiply matrix by vector
            Vector4d v_prime = new Vector4d(
                Vector4d.Dot(temp.Row0, point),
                Vector4d.Dot(temp.Row1, point),
                Vector4d.Dot(temp.Row2, point),
                Vector4d.Dot(temp.Row3, point)
                );
    
            v_prime = Vector4d.Divide(v_prime, v_prime.W);
    
            return new Vector3d(
                view[0] + view[2] * (v_prime.X + 1) / 2,
                view[1] + view[3] * (v_prime.Y + 1) / 2,
                (v_prime.Z + 1) / 2
                );
        }
    
        public static Vector3d UnProject(Vector3d window, Matrix4d modelview, Matrix4d projection, int[] view)
        {
            Matrix4d inv = Matrix4d.Mult(projection, modelview);
            inv.Invert();
    
            double vx = (2 * (window.X - view[0])) / view[2] - 1;
            double vy = (2 * (window.Y - view[1])) / view[3] - 1;
            double vz = (2 * window.Z) - 1;
    
            Vector4d vect = new Vector4d(vx, vy, vz, 1);
    
            // now multiply matrix times vector, which is really row (dot) vector for each value
            // correct, the bottom row of the inv matrix is unused
            return new Vector3d(
                Vector4d.Dot(inv.Row0, vect),
                Vector4d.Dot(inv.Row1, vect),
                Vector4d.Dot(inv.Row2, vect)
                );
        }
    
    2 回复  |  直到 8 年前
        1
  •  2
  •   Greg S    14 年前

    我不完全确定,但至少你的矩阵乘法的顺序 Project 函数可能出错。看一看 http://www.opengl.org/wiki/GluProject_and_gluUnProject_code 对于C代码,其中临时向量( v_prime 在您的代码中)是通过首先与ModelView矩阵相乘来计算的,然后结果依次与投影矩阵相乘。

    另一个好消息来源 gluProject / gluUnProject 实现是 http://www.mesa3d.org/ .

        2
  •  2
  •   Tesserex    14 年前

    我想出来了-我的矩阵需要换位。不知道为什么,但是OpenTK函数给出的模型矩阵与本机调用不同。