我试图通过将鼠标悬停在渲染世界的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
我也避免使用正投影法。