我使用的代码尝试像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.Position中作为3D空间中的模型存在的类。 但是我从中得到的价值天文数字远远超出了窗口界限。
断点的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)}
我做错了什么或者我弄错了什么?我错过了什么吗?
答案 0 :(得分:1)
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;
}
答案 1 :(得分:0)
在使用之前,您是否理智检查了s.Position值?你应用于矢量的投影和变换矩阵怎么样,它们看起来是否合理?
我不熟悉OpenTK,但set2DPos()之前的数学看起来足够合理。
答案 2 :(得分:0)
以下是它的工作原理:
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))
);
如果有人需要它:)