OpentTK +各种 z 值上的 Glu.UnProject() 不会给出重叠点

发布于 2024-12-20 02:21:25 字数 2155 浏览 2 评论 0原文

我在 C# 中使用 OpenTK,但在过去的几个小时里我一直碰壁。

我正在尝试使用 Glu.UnProject() 创建一条穿过用户单击的宇宙的射线。它追踪的光线对用户来说应该是不可见的,因为它是一条垂直于投影平面的线。

问题是,只有当我使用基本相机位置时,光线才不可见。如果我移动相机(cameraX 和cameraY),DrawLine 中的线条将显示在 UI 中。近点和远点与相机的“眼睛”不共线!

我在这里隔离了问题代码:

glSurface_Paint(Object sender, PaintEventArgs e) {
  double time = stopwatch.ElapsedMilliseconds * TimeScale + stopwatchOffset;

  GL.MatrixMode(MatrixMode.Projection);
  GL.LoadIdentity();

  Glu.Perspective(10, (double)Width / Height, nearClip, farClip);

  GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
  GL.MatrixMode(MatrixMode.Modelview);
  GL.LoadIdentity();
  Glu.LookAt(cameraX, cameraY, cameraZ * scaleFactor, 0, 0, 0, 0, 1, 0);
  GL.ClearColor(Color.DarkGray);

  if (ShowGrid) {
    DrawGrid();
  }

  DrawLine();

  glSurface.SwapBuffers();
}

Here is DrawLine。它使用硬编码值来取消投影近平面 (z = 0) 和远平面 (z = 1) 的 (100, 200) 处的点。然后它只是在这两点之间画一条线。

public void DrawLine() {
  int[] viewport = new int[4];
  double[] modelMatrix = new double[16];
  double[] projMatrix = new double[16];

  GL.GetInteger(GetPName.Viewport, viewport);
  GL.GetDouble(GetPName.ModelviewMatrix, modelMatrix);
  GL.GetDouble(GetPName.ProjectionMatrix, projMatrix);

  Vector3 clickNearPoint;
  Glu.UnProject(new Vector3(100, 200, 0), modelMatrix, projMatrix, viewport, out clickNearPoint);

  Vector3 clickFarPoint;
  Glu.UnProject(new Vector3(100, 200, 1), modelMatrix, projMatrix, viewport, out clickFarPoint);

  nearPoint = new Point3D(clickNearPoint.X, -clickNearPoint.Y, clickNearPoint.Z);
  farPoint = new Point3D(clickFarPoint.X, -clickFarPoint.Y, clickFarPoint.Z);

  if (nearPoint.HasValue && farPoint.HasValue) {
    GL.Color3(Color.White);

    GL.Begin(BeginMode.Lines);
    GL.Vertex3(nearPoint.Value.X, nearPoint.Value.Y, nearPoint.Value.Z);
    GL.Vertex3(farPoint.Value.X, farPoint.Value.Y, farPoint.Value.Z);
    GL.End();
  }
}

这是问题的屏幕截图。左边的线不应该出现!

在此处输入图像描述

我已经研究这个问题几个小时了,但我没有什么可尝试的。任何输入都会有很大的帮助。

附言。白线显示为黑色,因为我移除了光源以及演示该问题所不需要的所有内容。

I am using OpenTK in C# and I have been hitting a wall for the last few hours.

I'm trying to use Glu.UnProject() to create a ray through the universe where the user clicked. The ray it traces should be invisible to the user since it a line perpendicular to the plane of projection.

The problem is that the ray is only invisible when I'm using the basic camera position. If I move the camera (cameraX and cameraY), the line from DrawLine is displayed in the UI. The near and far points are not co-linear with the "eye" of the camera!

I isolated the problem code here :

glSurface_Paint(Object sender, PaintEventArgs e) {
  double time = stopwatch.ElapsedMilliseconds * TimeScale + stopwatchOffset;

  GL.MatrixMode(MatrixMode.Projection);
  GL.LoadIdentity();

  Glu.Perspective(10, (double)Width / Height, nearClip, farClip);

  GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
  GL.MatrixMode(MatrixMode.Modelview);
  GL.LoadIdentity();
  Glu.LookAt(cameraX, cameraY, cameraZ * scaleFactor, 0, 0, 0, 0, 1, 0);
  GL.ClearColor(Color.DarkGray);

  if (ShowGrid) {
    DrawGrid();
  }

  DrawLine();

  glSurface.SwapBuffers();
}

Here is DrawLine. It uses hard-coded values to un-project the points at (100, 200) for the near (z = 0) and far (z = 1) planes. It then simply draws a line between these two points.

public void DrawLine() {
  int[] viewport = new int[4];
  double[] modelMatrix = new double[16];
  double[] projMatrix = new double[16];

  GL.GetInteger(GetPName.Viewport, viewport);
  GL.GetDouble(GetPName.ModelviewMatrix, modelMatrix);
  GL.GetDouble(GetPName.ProjectionMatrix, projMatrix);

  Vector3 clickNearPoint;
  Glu.UnProject(new Vector3(100, 200, 0), modelMatrix, projMatrix, viewport, out clickNearPoint);

  Vector3 clickFarPoint;
  Glu.UnProject(new Vector3(100, 200, 1), modelMatrix, projMatrix, viewport, out clickFarPoint);

  nearPoint = new Point3D(clickNearPoint.X, -clickNearPoint.Y, clickNearPoint.Z);
  farPoint = new Point3D(clickFarPoint.X, -clickFarPoint.Y, clickFarPoint.Z);

  if (nearPoint.HasValue && farPoint.HasValue) {
    GL.Color3(Color.White);

    GL.Begin(BeginMode.Lines);
    GL.Vertex3(nearPoint.Value.X, nearPoint.Value.Y, nearPoint.Value.Z);
    GL.Vertex3(farPoint.Value.X, farPoint.Value.Y, farPoint.Value.Z);
    GL.End();
  }
}

Here is a screenshot of the problem. The line on the left should not appear!

enter image description here

I've been investigating this for hours and I'm out of things to try. Any input would be a great help.

PS. White lines appears black because I removed light sources and everything that wasn't necessary to demonstrate the issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风铃鹿 2024-12-27 02:21:25
Vector3 clickNearPoint;
  Glu.UnProject(new Vector3(100, 200, 0), modelMatrix, projMatrix, viewport, out clickNearPoint);

  Vector3 clickFarPoint;
  Glu.UnProject(new Vector3(100, 200, 1), modelMatrix, projMatrix, viewport, out clickFarPoint);

  nearPoint = new Point3D(clickNearPoint.X, -clickNearPoint.Y, clickNearPoint.Z);
  farPoint  = new Point3D(clickFarPoint.X,  -clickFarPoint.Y,  clickFarPoint.Z);
                                            ^
                                            ^

为什么要对返回的 Y 坐标取反?这可能是导致您的问题的原因。

Vector3 clickNearPoint;
  Glu.UnProject(new Vector3(100, 200, 0), modelMatrix, projMatrix, viewport, out clickNearPoint);

  Vector3 clickFarPoint;
  Glu.UnProject(new Vector3(100, 200, 1), modelMatrix, projMatrix, viewport, out clickFarPoint);

  nearPoint = new Point3D(clickNearPoint.X, -clickNearPoint.Y, clickNearPoint.Z);
  farPoint  = new Point3D(clickFarPoint.X,  -clickFarPoint.Y,  clickFarPoint.Z);
                                            ^
                                            ^

Why are you negating the returned Y coordinates? This is likely the cause of your problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文