Manually projecting 3d coordinates onto the 2d screen can be useful as seen above to label objects (although you can do a similar thing with billboards), it can also be used to create a kind of 3d radar effect (think Elite)
The maths behind this are fairly straight forward, a 4D vector (x,y,z,1) is multiplied with a “model” matrix (describing the orientation and position of your model) and finally by the perspective matrix, which is in effect your camera. This is a tried and tested method and indeed I ported the code from the gluProject function to do this. The information we get back also includes the depth into the screen and can be used at the least so we don’t need to render labels that are behind the camera. The W component can also be useful to effect the transformation, which is used to create the 3d “radar”.
One big disadvantage of rendering in 2d is that you lack a depth buffer, this might or might not be an issue depending what you want to do, but at the least we really need to sort the labels by depth. It can be useful not to have labels obscured by nearby geometry, however the alternative is to code your own 3d text renderer (you’d also need to be careful about translating the label closer to your camera)
As a bonus, you have all the information to draw an Elite style radar, simply by dividing the 2d coordinates by the W component as mentioned previously, you could instead use the same information to render a horizontal compass by using just the x coordinate.
I have found this method useful in the past when debugging things often on a 2d space it can be hard to organise debug data, if data is actually “attached” to the 3d object concerned then things are all together more intuitive…
If you think this might be useful you can find the code here.