
How to display simple 2D text labels at 3D positions?
Posted Sunday, 24 May, 2009 - 13:36 by codester inHello,
For my current project I need the following funcionality:
The program displays celestial bodies at their positions (3D). This is what I've done so far using OpenTK. I'd now like to display text labels at the positions of the bodies. In general I want to display 2D text at any position in 3D space.
The result should look similar to this. The screenshot was taken from GMAT, an open source project. Of course I already tried to search their code for a solution but there are tot many files containing floods of cryptic c++. I also tried to find a solution in these forums and in the example sources on this page but the only thing I've accomplished was this.
VB code I've used:
Private Sub drawString(ByVal s As String, ByVal position As Vector3, ByVal color As Color) Using printer As New OpenTK.Graphics.TextPrinter printer.Print(s, SystemFonts.DefaultFont, color) End Using End Sub
Is there another way to print text? (I've read this but I can't believe that it's that difficult to print a simple string?)
[Mod hint: use <code lang="vbnet"> for to prettify vb.net code]


Comments
Re: How to display simple 2D text labels at 3D positions?
I think gluProject is the answer here. Try this:
This code mimics Glu.Project(): it tries to project the 3d point onto the monitor and print text there.
Disclaimer: didn't test this on a compiler and I've probably multiplied the matrices the wrong way round. Play around with the parameters if this doesn't work at first.
Text printing is a very complex topic. Suffice to say that FreeType (an open source library that renders glyphs) contains 260K lines of code. If you add text layout into the mix, you could easily hit the 500K mark.
Re: How to display simple 2D text labels at 3D positions?
Hello,
thanks for helping me but your code doesn't work. It doesn't even compile since GL.GetFloat expects modelview and projection to be a Single and GL.GetInteger requires an integer.
I also tried to use GL.Project but since I don't know where to get the parameters this wasn't a success either.
I don't want to complain but why doesn't TextPrinter make it easier to accomplish such tasks?
Re: How to display simple 2D text labels at 3D positions?
As I said, I didn't run the code through the compiler. Updated code:
Reference: gluProject
TextPrinter draws 2d text on screen. It's your responsibility to tell it *where* to draw the text. TextPrinter has no idea what kind of projection you are using and, indeed, if you are even using the deprecated OpenGL matrix stack.
Re: How to display simple 2D text labels at 3D positions?
I dont think textprinter should care about unprojecting.
Fiddler showed a standard approach of projecting the 3d coordinates to screen space.
My sample code is C# using Glu.Project and a WinForms-Control named glControl1 :
Re: How to display simple 2D text labels at 3D positions?
Thanks again for your help.
Still your code doesn't compile. At least I failed so far. Do you test it with VS 08 Visual Basic compiler? And, just to be sure, we are talking about OpenTK 0.9.7 aren't we? Here's what I get with your code:
Re: How to display simple 2D text labels at 3D positions?
@ entity: In function "WorldToScreen", what are "Viewport", "ModelViewMatrix" and "ProjectionMatrix" declared as? (And where? Or is there something like "Option Explicit Off" (Visual Basic) in C#, too?)
Re: How to display simple 2D text labels at 3D positions?
You are right about viewport, it should be an array of 4 items.
The necessary GetFloat overloads are not available in OpenTK 0.9.7, so you'll have to the calls like this:
This is decidedly non-intuitive, I'll make sure the necessary overloads exist in OpenTK 0.9.8.
The fields in entity's code are presumably
Double(16)(projection, modelview) andInteger(4)(viewport) arrays.Edit: overloads now in SVN.
Re: How to display simple 2D text labels at 3D positions?
Thanks for your help. It works very nice
Re: How to display simple 2D text labels at 3D positions?
Indeed, looks very nice.
Judging from the form of the letters, it looks like cleartype is off? If you look closely, "Sol" and "Earth" look somewhat blurry. You can fix this by enabling cleartype (which effectively triples horizontal resolution). Alternatively, you can "snap" text to integer positions - animation will be less smooth, but text will stay crisp even without cleartype:
For best results, you can combine both approaches: enable cleartype and snap text.
Re: How to display simple 2D text labels at 3D positions?
Hi,
I don't see any advantage in cleartype but text snap text looks interesting. Will try it...