在没有GLUUNPROJECT的情况下将屏幕坐标转换为世界坐标 [英] Convert screen coordinate to world coordinate WITHOUT GLUUNPROJECT

查看:80
本文介绍了在没有GLUUNPROJECT的情况下将屏幕坐标转换为世界坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在Google和这个网站上寻找答案,但是我仍然对如何将屏幕上的坐标转换为模型空间中的坐标感到困惑.我确实知道从原点(0,0,0)到我的相机的距离,这也是视口的中心:

I have been searching all over with Google and this site for an answer but I still get confused as to how one goes about converting the coordinates on the screen to the coordinate in model space. I do know the distance from the origin (0,0,0) to my camera, which is also the viewport's center:

如果我的视图窗口上有其他点,例如(1,3):

If I have a different point on my view window such as (1,3) for example:

在模型视图中数学计算新点或使用矩阵函数确定新点的最佳方法是什么?

What is the best way to either mathematically calculate the new point in model view or to use matrix functions to determine it?

对于某些人认为这是简单"的事情,我深表歉意,但我希望有人会使用我的样本坐标发布一个很好的例子,因为我仍然很困惑.

I apologize if this is considered "easy" for some people but I was hoping someone would post a good example using my sample coordinate since I am still rather confused.

这是在每一帧上进行的矩阵调用:

Here is the matrix call that is done on every frame:

Public Sub SetupViewport()
    Dim w As Integer = GlControl1.Width
    Dim h As Integer = GlControl1.Height
    Dim perspective1 As Matrix4 = cam.GetViewMatrix() * Matrix4.CreatePerspectiveFieldOfView(1.3F, ClientSize.Width / CSng(ClientSize.Height), 0.1F, 200.0F)


    GL.MatrixMode(MatrixMode.Projection)
    GL.LoadIdentity()
    GL.LoadMatrix(perspective1)
    GL.Viewport(0, 0, w, h)

End Sub

这样做是为了允许我使用凸轮矩阵旋转相机.我通常在Open GL中知道您旋转场景而不是摄影机,但是由于我将其用作CAD程序,因此我将摄影机绕原点旋转.

This is done to allow me to rotate the camera using the cam matrix. I know generally in Open GL that you rotate the scene and not the camera but since I am using this as a CAD program, I am rotating my camera around the origin.

出于测试目的,我一直在构建一条从计算出的起点到起点的直线.如标题所示,我不希望使用gluunproject,因为我已经阅读到这是基于Tao框架的,因此不应该使用.

For testing purposes I have been constructing a line from what I calculate as the calculated start point, to the origin. As the title states, I do not wish to use gluunproject since I have read that this is based off of Tao framework so shouldn't be used.

我的绘画子

Private Sub GlControl1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles GlControl1.Paint

    GL.Clear(ClearBufferMask.ColorBufferBit)
    GL.Clear(ClearBufferMask.DepthBufferBit)
    GL.DepthMask(True)
    GL.Enable(EnableCap.DepthTest)
    GL.ClearDepth(1.0F)



    GL.MatrixMode(MatrixMode.Modelview)
    GL.LoadIdentity()


    Dim lightColor0 As Single() = {intensity, intensity, intensity, 1.0F}
    Dim lightPos0 As Single() = {camx, camy, camz, 1.0F}


    GL.Light(LightName.Light0, LightParameter.Diffuse, lightColor0)
    GL.Light(LightName.Light0, LightParameter.Position, lightPos0)
    GL.Enable(EnableCap.Light0)



    Dim mat_specular As Single() = {1.0F, 1.0F, 1.0F, 1.0F}
    Dim mat_shininess As Single() = {50.0F}


    GL.Material(MaterialFace.Front, MaterialParameter.Specular, mat_specular)
    GL.Material(MaterialFace.Front, MaterialParameter.Shininess, mat_shininess)


    GL.Disable(EnableCap.Lighting)

    GL.Begin(PrimitiveType.Lines)
    GL.Color3(Color.Red)
    GL.Vertex3(0, 0, 0)
    GL.Vertex3(100, 0, 0)

    GL.Color3(Color.Green)
    GL.Vertex3(0, 0, 0)
    GL.Vertex3(0, 100, 0)

    GL.Color3(Color.Blue)
    GL.Vertex3(0, 0, 0)
    GL.Vertex3(0, 0, 100)
    GL.End()


    GL.Begin(PrimitiveType.Lines)
    GL.Color3(Color.DarkRed)
    GL.Vertex3(0, 0, 0)
    GL.Vertex3(-100, 0, 0)

    GL.Color3(Color.DarkGreen)
    GL.Vertex3(0, 0, 0)
    GL.Vertex3(0, -100, 0)

    GL.Color3(Color.DarkBlue)
    GL.Vertex3(0, 0, 0)
    GL.Vertex3(0, 0, -100)
    GL.End()

    Dim projmatrix As Matrix4
    GL.GetFloat(GetPName.ProjectionMatrix, projmatrix)
    Dim mouse_ As New Vector2(_mouseStartX, _mouseStartY)
    Dim returnvec As Vector4

    returnvec = UnProject(projmatrix, cam.GetViewMatrix(), GlControl1.Size, mouse_)

    GL.Begin(PrimitiveType.Lines)
    GL.Color3(Color.Orange)
    GL.Vertex3(0, 0, 0)
    GL.Vertex3(returnvec.X, returnvec.Y, returnvec.Z)
    GL.End()


    GL.Enable(EnableCap.Lighting)

    draw_extras()


    GL.Flush()
    GlControl1.SwapBuffers()
End Sub

推荐答案

感谢datenwolf让我走上正确的道路.解决问题的方法是在一些站点的帮助下编写了一个unproject函数:

Thank you datenwolf for getting me down the right path. What I have done to solve my problem is I wrote an unproject function, with help of a few sites:

Public Shared Function UnProject(ByRef projection As Matrix4, view As Matrix4, viewport As Size, mouse As Vector2) As Vector4
    Dim vec As Vector4

    vec.X = 2.0F * mouse.X / CSng(viewport.Width) - 1
    vec.Y = -(2.0F * mouse.Y / CSng(viewport.Height) - 1)
    vec.Z = 0
    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

我有一个鼠标移动事件处理程序,该事件处理程序仅捕获屏幕上鼠标的位置并将坐标保存到两个全局变量中.在我的draw函数中,然后调用我的新函数并绘制一条从原点延伸到我的线鼠标位置:

I have a mouse move event handler that simply captures the mouse location on the screen and saves the coordinates to two global variables.. Within my draw function I then call my new function and draw a line that extends from the origin to my mouse position:

Dim projmatrix As Matrix4
    GL.GetFloat(GetPName.ProjectionMatrix, projmatrix)
    Dim modelmatrix As Matrix4
    GL.GetFloat(GetPName.ModelviewMatrix, modelmatrix)

    Dim mouse_ As New Vector2(_mouseStartX, _mouseStartY)
    Dim returnvec As Vector4

    returnvec = UnProject(projmatrix, modelmatrix, GlControl1.Size, mouse_)

    GL.Begin(PrimitiveType.Lines)
    GL.Color3(Color.Orange)
    GL.Vertex3(0, 0, 0)
    GL.Vertex3(returnvec.X, returnvec.Y, returnvec.Z)
    GL.End()

我还必须更改setupviewport函数:

I also had to change my setupviewport function:

Public Sub SetupViewport()
    Dim w As Integer = GlControl1.Width
    Dim h As Integer = GlControl1.Height

    Dim perspective1 As Matrix4 = cam.GetViewMatrix() * Matrix4.CreatePerspectiveFieldOfView(1.3F, ClientSize.Width / CSng(ClientSize.Height), 0.1F, 200.0F)


    GL.MatrixMode(MatrixMode.Projection)
    GL.LoadIdentity()
    GL.LoadMatrix(perspective1)
    GL.MatrixMode(MatrixMode.Modelview)
    GL.LoadIdentity()
    GL.Viewport(0, 0, w, h)
    GL.Enable(EnableCap.DepthTest)
    GL.DepthFunc(DepthFunction.Less)

End Sub

结果是一行始终在原点上,而另一侧始终在鼠标上,这是展示此功能的绝佳示例.

The result is a line that has one side always on the origin and the other side always where the mouse is which is a fantastic example to show this working.

这篇关于在没有GLUUNPROJECT的情况下将屏幕坐标转换为世界坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆