smarrocco's picture

Projecting 3D points oddity

I've setup a simple scene that allows me to experiment with some simple shape rendering in a GLControl using perspective. All the drawing performs as expected. At one point I attempt to add some text using the QuickFont library; the text is fine, but in trying to track the text to one of the vertices' 3D locations I'm seeing some strange results. The text is not tracking the point properly--I believe the problem is within the Project() function I've attempted to use. One particular thing I've noticed is that the text moves/tracks differently if I change the ClipNear/ClipFar plane distances. This seems odd--I don't understand why the Project() function would return different results when the clipping planes move.

I would appreciate any suggestions anyone can offer, in particular to my Project() function (which I obtained from a post on these forums).

Private Sub Draw(CamX as double, CamY as double, CamZ as double, ClipNear as double, ClipNear as double, ClipFar as double)
 
gl.viewport(0,0,GlControl1.Width,GlControl1.Height)
 
Dim projection As Matrix4 = Matrix4.CreatePerspectiveFieldOfView(PI / 4, GlControl1.Width / GlControl1.Height, ClipNear, ClipFar)
GL.MatrixMode(MatrixMode.Projection)
GL.LoadMatrix(projection)
 
GL.Clear(ClearBufferMask.ColorBufferBit Or ClearBufferMask.DepthBufferBit)
 
Dim modelview As Matrix4 = Matrix4.LookAt(CamX, CamY, CamZ, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
GL.MatrixMode(MatrixMode.Modelview)
GL.LoadMatrix(modelview)
 
GL.ClearColor(Color.SkyBlue)
'Draw a triangle
GL.Begin(BeginMode.LineLoop)
GL.Color3(Color.Red)
GL.Vertex3(0, 0, 0)
GL.Vertex3(0.5, 0, 0)
GL.Vertex3(0, 1, 0)
GL.End()
 
'Draw text that tracks the last vertex of the triangle
QFont.Begin()
Dim dPoint As Vector2 = Project(New Vector3(0, 1, 0), modelview, projection, w, h)
MyQFont.Options.Colour = New OpenTK.Graphics.Color4(0, 0, 255, 255)
MyQFont.Options.UseDefaultBlendFunction = False
MyQFont.Print("Tracking Text", dPoint)
QFont.End()
GL.Disable(EnableCap.Texture2D)
 
GL.Flush()
 
GlControl1.SwapBuffers()
End Sub
 
 
Private Function Project(pos As Vector3, viewMatrix As Matrix4, projectionMatrix As Matrix4, screenWidth As Integer, screenHeight As Integer) As Vector2
pos = Vector3.Transform(pos, viewMatrix)
pos = Vector3.Transform(pos, projectionMatrix)
pos.X /= pos.Z
pos.Y = -pos.Y / pos.Z
pos.X = (pos.X + 1) * screenWidth / 2
pos.Y = (pos.Y + 1) * screenHeight / 2
 
Return New Vector2(pos.X, pos.Y)
End Function