0

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.

4

1 回答 1

1
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 坐标?这可能是您的问题的原因。

于 2011-12-06T08:04:57.330 回答