I spent the past few days implementing and profiling different font rendering methods, and I'm glad to say that OpenTK can now render text at an impressive rate of ~1.25 million characters per second. This is the best-case situtation where all text is rendered in one batch, but the gist is that text rendering has negligible impact on performance.
I've also tried to improve text rendering at small point sizes, but this didn't work out so well. To get pixel-perfect glyph rendering, you have to disable OpenGL texture filtering, however, by doing so you stop benefiting from sub-pixel precision making text look really bad. You can improve quality by enabling grid-fitting and making absolutely sure that every glyph is rendered at whole pixel boundaries. This isn't really practical (scrolling text suddenly becomes a very interesting problem!), so I've compromised by enabling filtering and increasing text contrast to compensate. Grid-fitting is still enabled for small point sizes (16 or less), but disabled for larger text where sub-pixel precision allows us to have better shapes. I'm not 100% content with the looks of the text, but this can be tweaked in the future.
On the implementation side, rendering text involves four steps:
- Load a TextureFont with the desired type face and size.
- Create a TextPrinter suitable for the script you wish to render. OpenTK will provide a simple TextPrinter with support for word wraping, text alignment and right-to-left rendering, but you will be able to provide your own implementation e.g. for complex scripts or vertical rendering. Such implementations could also be provided as add-in modules in the future.
- Use the TextPrinter.Prepare() method to prepare your text for rendering and obtain a TextHandle.
- Use TextPrinter.Draw() with the TextHandle to render your text at any time.
The first two should only be done during start up. There will also be a way to render dynamic text without caching, at a (small) performance hit. The current implementation can render up to 8192 characters in one batch (about two full pages of text) - although most games rarely display more than a few hundred characters at once.
I hope to have 0.3.13 ready for release by the end of this week. There's still quite some work to do, input is broken on Linux and Win9x, the examples need cleaning up (vertex arrays are totally botched on dual-core machines), and I'd like to have some documentation ready as well. Till next time!