Я пытаюсь получить мировые координаты, наведя указатель мыши на GLControl
элемент управления, в котором отображается мир. Я нашел десятки примеров и решений, но я не могу с ними работать, я все еще учусьи не дошел до своей точки.Но я продолжал копать, нашел несколько примеров и выбрал тот, который одобрен его оригинальным автором, который работает с подобной конструкцией рендера, но все еще не работает для меня.
Я установил окно для вывода преобразованных координат.Я получаю x, y = 0
в центре контроля, что означает, что я, возможно, иду по правильному пути.Когда я перемещаю мышь вокруг осей x
и y
, она выдает правильные значения (например, чем выше мышь от центра элемента управления, тем выше y
и т. Д.), Но только на уровне -1.65/1.65
Макс от центра.Не похоже, что он получает мою матрицу Modelview
, потому что она должна отличаться в зависимости от eyeZ
, чего нет.Изменение eyeZ
не имеет никакого эффекта.Он по-прежнему действует так, как если бы я не «увеличивал / уменьшал».
Я настроил Projection
, Modelview
матрицы и Viewport
так:
GL.MatrixMode(MatrixMode.Projection)
GL.LoadIdentity()
GL.LoadMatrix(Matrix4.CreatePerspectiveFieldOfView(Math.PI / 4, glControl.Width / glControl.Height, 1.0F, 128.0F))
GL.MatrixMode(MatrixMode.Modelview)
GL.LoadIdentity()
GL.LoadMatrix(Matrix4.LookAt(0F, 0F, zoom, 0F, 0F, 0F, 0F, 1.0F, 0F))
GL.Viewport(0, 0, glControl.Width, glControl.Height)
Затем у меня есть эти две функции, которые вызываются, когда моя мышь перемещается над GLControl
и передают координаты мыши.
Public Function screenToWorld(ByVal x As Integer, ByVal y As Integer) As Vector4
Dim modelViewMatrix As Matrix4
Dim projectionMatrix As Matrix4
Dim viewport(4) As Integer
GL.GetFloat(GetPName.ModelviewMatrix, modelViewMatrix)
GL.GetFloat(GetPName.ProjectionMatrix, projectionMatrix)
GL.GetInteger(GetPName.Viewport, viewport)
Return UnProject(projectionMatrix, modelViewMatrix, New Size(viewport(2), viewport(3)), New Vector2(x, y))
End Function
Public Function UnProject(ByRef projection As Matrix4, ByVal view As Matrix4, ByVal viewport As Size, ByVal mouse As Vector2) As Vector4
Dim vec As Vector4
vec.X = 2.0F * mouse.X / viewport.Width - 1
vec.Y = -(2.0F * mouse.Y / viewport.Height - 1)
vec.Z = 0F
vec.W = 1.0F
Dim viewInv As Matrix4 = Matrix4.Invert(view)
Dim projInv As Matrix4 = Matrix4.Invert(projection)
Vector4.Transform(vec, projInv, vec)
Vector4.Transform(vec, viewInv, vec)
If vec.W > Single.Epsilon OrElse vec.W < Single.Epsilon Then
vec.X /= vec.W
vec.Y /= vec.W
vec.Z /= vec.W
End If
Return vec
End Function
Также я воздерживаюсь от использования ортографической проекции.