Text! Yay!

That one was surprisingly easy, then hard, and eventually pretty easy again.

In most GUI-frameworks, I think, one could have just used the normal text-on-canvas functions to draw some text on top of the OpenGL canvas. At least that’s what I had expected.

Well, it doesn’t really work that way in Racket’s GUI framework. So, text rendering in OpenGL it is.

Some googling later, I was horrified – the way one renders text in OpenGL is basically the following:

  • obtaining a bitmap of the text
  • converting that to a texture
  • mapping that texture onto an object
  • rendering the object

But I figured I had no choice. Off to Racket’s documentation (which is excellent, by the way) for point one on the list: obtaining a bitmap with text on it.

That’s really easy in racket:

(let* ([text-target (make-bitmap 200 200)]
       [dc (new bitmap-dc% [bitmap text-target])])
  (send dc draw-text "hello, world!"))

All right, now – how can I convert that to an OpenGL texture? Turns out, I don’t have to. There’s a handy function which directly converts that bitmap into an OpenGL display-list – ready for rendering.

(gl-call-list (bitmap->gl-list text-target))

So, at the end of the day, that was quite easy. It’s not perfect (the letters look pretty bad and turning on font-smoothing only makes it worse) but good enough for now. And there’s an up-side: the text-holding object behaves like any other 3D object in the scene, now. It can be textured, reacts to the scene’s lightening, etc.

Screenshot:

(Please ignore the ugly wood-panel background, that’s only there because it was easy to do.)

Leave a Reply

Your email address will not be published. Required fields are marked *

Your post must include a link to this post.

How does this work?
Write a response on your own website and include a link to this post. Then submit your response’s URL here. Your response may appear here after moderation. To update or remove it, edit or delete your original post and submit the same URL again. Learn more about Webmentions.