سؤال

أنا أستخدم Opentk في لعبة في C#، ولا تأتي مع وظائف المشروع ووظائف غير المشروع ، والتي تتحول بين إحداثيات العالم وإحداثيات الشاشة. حسنًا ، هذا الأمر كذلك ، لكنهم تم إهمالهم ولم أستطع حملهم على العمل. أخذت رصاصة في تنفيذها بنفسي بناءً على OpenGL Spec (انظر القائمة اليسرى ، Gluproject و GluunProject ، والعرض في FF ، وليس الكروم). شاهد تلك الصيغ ، أحاول مطابقتها. وظائفي لا تعمل على الإطلاق ، فإن النقاط التي يعيدها المشروع تقع كلها بالقرب من مركز شاشتي ، وقريبة جدًا من بعضها البعض ، على الرغم من أنني أحرك نقطة العالم في كل مكان.

لاحظ أن Opentk's Math Lib لا يتضمن وظائف لضرب المصفوفة بواسطة متجه ، لذلك قمت للتو بصفتي صف من منتجات Vector Dot لكل إدخال في المتجه الناتج (هذا صحيح ، أليس كذلك؟)

    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

لقد اكتشفت ذلك - يجب نقل المصفوفات الخاصة بي. لا أعرف لماذا ، لكن وظائف Opentk أعطت مصفوفاتي النموذجية بشكل مختلف عن المكالمات الأصلية.

نصائح أخرى

لست متأكدًا تمامًا ، ولكن على الأقل ترتيب مضاعفات المصفوفة في Project قد تكون الوظيفة خاطئة. ألق نظرة على http://www.opengl.org/wiki/gluproject_and_gluunproject_code للرمز C ، حيث المتجه المؤقت (v_prime في الكود الخاص بك) يتم احتسابها عن طريق الضرب مع مصفوفة ModelView أولاً ، ثم يتم مضاعفة النتيجة بدورها مع مصفوفة الإسقاط.

مصدر جيد آخر للبحث عن gluProject/gluUnProject التنفيذ هو http://www.mesa3d.org/.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top