首页 > 解决方案 > UnProject 缩放时无法获取世界坐标

问题描述

在我的 SharpGL 项目 (C#) 中,我使用了 Unproject 函数来从鼠标坐标中获取世界坐标。

此过程非常简单,但在缩放绘图时会失败。我找到了很多关于这个问题的文章,但没有一篇适合我。

当我说缩放意味着在draw main proc中我应用此代码:

_gl.Scale(_params.ScaleFactor, _params.ScaleFactor, _params.ScaleFactor);

然后,当我拦截鼠标移动时,我想可视化世界坐标。当比例因子为 1 时,这些坐标是精确的,但是当我改变它时,这些坐标是错误的。

例如:一个世界点 (10, 10) 检测到缩放 1 (10, 10) 检测到缩放 1,25 (8, 8) 检测到缩放 1,25 (6.65, 6.65)

这是我的简单代码,考虑到 scale_factor 只是用于调试。

public static XglVertex GetWorldCoords(this OpenGL gl, int x, int y, float scale_factor)
    {
        double worldX = 0;
        double worldY = 0;
        double worldZ = 0;
        int[] viewport = new int[4];
        double[] modelview = new double[16];
        double[] projection = new double[16];

        gl.GetDouble(OpenGL.GL_MODELVIEW_MATRIX, modelview); //get the modelview info
        gl.GetDouble(OpenGL.GL_PROJECTION_MATRIX, projection); //get the projection matrix info
        gl.GetInteger(OpenGL.GL_VIEWPORT, viewport); //get the viewport info

        float winX = (float)x;
        float winY = (float)viewport[3] - (float)y;
        float winZ = 0;

        //get the world coordinates from the screen coordinates
        gl.UnProject(winX, winY, winZ, modelview, projection, viewport, ref worldX, ref worldY, ref worldZ);
        XglVertex vres = new XglVertex((float)worldX, (float)worldY, (float)worldZ);
        Debug.Print(string.Format("World Coordinate: x = {0}, y = {1}, z = {2}, sf = {3}", vres.X, vres.Y, vres.Z, scale_factor));

        return vres;
    }

在此处输入图像描述

标签: openglsharpgl

解决方案


我找到了解决办法!

在主绘图过程中有一部分代码会改变 UnProject 函数的结果。

gl.PushMatrix();
.Translate(_mouse.CursorPosition.X * _params.ScaleFactor, _mouse.CursorPosition.Y * _params.ScaleFactor, _mouse.CursorPosition.Z * _params.ScaleFactor);


foreach (var el in _cursor.Elements) //objects to be drawn
{
    gl.LineWidth(1f);
    gl.Begin(el.Mode);
    foreach (var v in el.Vertex)
    {
        gl.Color(v.Color.R, v.Color.G, v.Color.B, v.Color.A);
        gl.Vertex(v.X, v.Y, v.Z);
    }
    gl.End();
 
}
gl.PopMatrix();

推荐阅读