GL Project не работает должным образом - PullRequest
2 голосов
/ 30 ноября 2010

Я использую код, который пытается работать как Glu.Project (), поскольку OpenTK не поддерживает Glu.

        Vector4 pos = new Vector4(s.Position.X, 0.0f, s.Position.Y, 1.0f);
        Matrix4 mov = new Matrix4();
        Matrix4 prj = new Matrix4();
        Matrix4 mpj = new Matrix4();
        float[] vp = new float[4];

        GL.GetFloat(GetPName.ModelviewMatrix, out mov);
        GL.GetFloat(GetPName.ProjectionMatrix, out prj);
        GL.GetFloat(GetPName.Viewport, vp);

        Matrix4.Mult(ref prj, ref mov, out mpj);
        Vector4.Transform(ref pos, ref mpj, out pos);

        // Final mathematics as described in OpenGL 2.1 Glu specs
        s.set2DPos(new Vector2f( (vp[0] + (vp[2] * (pos.X + 1) / 2.0f)),
                                (vp[1] + (vp[3] * (pos.Y + 1) / 2.0f)) ));

        // Final mathematics as described in OpenGL 3 Vector specs
        s.set2DPos(new Vector2f( (view[2] / 2 * pos.X + view[0]),
                                (view[3] / 2 * pos.X + view[1]) ));

        // Neither of them work, but in relation OpenGL 3 vector specs work better.

s - это класс, который изначально существует как модель в трехмерном пространстве в s.Position. Но значения, которые я получаю из этого, астрономически далеко выходят за границы окна.

Матрица ModelView с точки останова:

{(1, 0, 0, 0)
(0, 0.7071068, 0.7071068, 0)
(0, -0.7071068, 0.7071068, 0)
(0, -141.4214, -141.4214, 1)}

Матрица проекции с точкой останова:

{(1.931371, 0, 0, 0)
(0, 2.414213, 0, 0)
(0, 0, -1.0002, -1)
(0, 0, -2.0002, 0)}

Я что-то не так делаю или я что-то не так понял? Я что-то упустил?

Ответы [ 3 ]

1 голос
/ 11 июля 2012
    Vector2 GetScreenCoordinates(Vector3 ObjectCoordinate)
    {
        // ref: http://www.songho.ca/opengl/gl_transform.html
        Vector4 obj = new Vector4(ObjectCoordinate.X, ObjectCoordinate.Y, ObjectCoordinate.Z, 1.0f);
        Matrix4 projection = new Matrix4();
        Matrix4 modelView = new Matrix4();
        Vector4 viewPort = new Vector4();

        GL.GetFloat(GetPName.ModelviewMatrix, out modelView);
        GL.GetFloat(GetPName.ProjectionMatrix, out projection);
        GL.GetFloat(GetPName.Viewport, out viewPort);

        Vector4
            eye = Vector4.Transform(obj, modelView),
            clip = Vector4.Transform(eye, projection);
        Vector3
            ndc = new Vector3(clip.X / clip.W, clip.Y / clip.W, clip.Z / clip.W);
        Vector2
            w = new Vector2(viewPort.Z / 2 * ndc.X + viewPort.X + viewPort.Z / 2,
                            viewPort.W / 2 * ndc.Y + viewPort.Y + viewPort.W / 2);

        return w;
    }
0 голосов
/ 06 декабря 2010

Вот как это работает:

GL.GetFloat(GetPName.ModelviewMatrix, out model);
GL.GetFloat(GetPName.ProjectionMatrix, out proj);
GL.GetFloat(GetPName.Viewport, view);

Matrix4.Transpose(ref model, out model);
Matrix4.Transpose(ref proj, out proj);

Vector4 posa = new Vector4(0.0f, s.Position.Y, 1.0f, s.Position.X);
Vector4 posb = new Vector4(s.Position.Y, 1.0f, s.Position.X, 0.0f);
Vector4 posc = new Vector4(1.0f, s.Position.X, 0.0f, s.Position.Y);

Vector4 one = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Matrix4 posv = new Matrix4(pos, posa, posb, posc);

Matrix4 ProjPos = Matrix4.Mult(Matrix4.Mult(proj, model), posv);
Matrix4.Transpose(ref ProjPos, out ProjPos);

Vector2f posout = new Vector2f(
   (0 + (this.glc.Width * (ProjPos.Column0.X / ProjPos.Column0.W + 1.0f)) - (this.glc.Width / 2.0f)),
   (0 + (this.glc.Height * (ProjPos.Column0.Y / ProjPos.Column0.W + 1.0f)) - (this.glc.Height / 2.0f))
);

На случай, если это кому-нибудь понадобится:)

0 голосов
/ 01 декабря 2010

Проверяли ли вы здравомыслие значение s.Position перед его использованием? Как насчет матриц проекции и преобразования, которые вы применяете к вектору, они выглядят вменяемым?

Я не знаком с OpenTK, но математика до set2DPos () выглядит достаточно разумной.

...