the Fiddler.'s picture

Progress: Fonts and Timing

Edit: breakthrough! I've discovered a way to write a fully managed font engine, without tapping into unmanaged code. The attached screenshot shows what to expect!

After some research, I’ve abandoned the idea of using wgl/glx functions for font rendering. I want OpenTK to support for high quality bitmap and outline fonts, and the above solution simply isn’t delivering.

I’m still evaluating available options, but I’m currently leaning towards Freetype2. Writing Freetype2 bindings is quite a lot of work (though certainly less than the OpenGL or GLX ones), and it will probably push the first stable release back, but it’s doable. This will be an important feature for OpenTK, as support for font rendering is sorely lacking in the (free) managed OpenGL landscape.

On another front, I’ve improved the timing algorithm in the GameWindow main loop. The new algorithm can achieve ‘perfect’ timing (less than 1% error) for frequencies up to 200Hz, where the one included in 0.3.12 could overshoot 10% or more. The only missing piece of the timing puzzle is a self-calibration routine for the CPU-yielding feature. Different systems have different granularities for Timer.Sleep(), which can go up to 10ms – obviously it is very bad to call Timer.Sleep(1) and sleep for 10ms when you don’t expect it. What the calibration routine will do is detect the minimum sleep granularity and use that as a scale to ensure that Timer.Sleep() never overshoots the target.

One more very useful feature (implemented in svn) is that GameWindow can now report accurate timing information (i.e. how long it took to update or render a frame, how many fps are you getting etc). You can use this data to scale object movement so that it looks good on any screen refresh rate:

Imagine a scenario where your object update rate is fixed at 60 updates per second (a reasonable value). If you render at 60fps (the refresh rate of most TFT’s), you will get perfectly smooth movement on TFT’s but very jerky motion on CRT’s (which typically operate at 75 or 85Hz). To combat this, you can either use a variable update rate, which is more complicated (you have to scale physics calculations by the time delta between frame updates and take into account instability for very small deltas!) or use a fixed update rate and interpolation to smooth out object movement during rendering.

All three solutions will be trivial to set up in OpenTK:

using (GameWindow gw = new GameWindow())
{
    gw.CreateWindow(new DisplayMode(800, 600));
    gw.UpdateFrame += YourUpdateFunction;
    gw.RenderFrame += YourRenderFunction;
    // Fixed update and render frequencies.
    // Looks bad on monitors with refresh rate different than 60Hz,
    // unless the "YourRenderFrame" function performs interpolation.
    // Use RenderFrameEventArgs.Scale to perform interpolation.
    gw.Run(60.0, Screen.RefreshRate);
    // Variable update frequency, fixed render frequency.
    // Looks good on all monitors, but "YourUpdateFrame" function will
    // be more complicated.
    // Use UpdateFrameEventArgs.Time to scale movement.
    gw.Run(0.0, Screen.RefreshRate);
}

Stay tuned for a more detailed article on this topic!

AttachmentSize
opentk_fonts.jpg84.91 KB

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
itaibh's picture

Regarding font rendering:
When writing software, I often need to use Hebrew script in the UI. This is also true when writing text in a graphic window.
Does the font rendering engine you wrote support RTL scripts such as Hebrew and Arabic? If not, please let me do some PR to NBidi, which is a library I wrote that implements the BIDI algorithm, just for such cases.
http://nbidi.sf.net
Itai.

the Fiddler.'s picture

Thanks for the link; I’ll add it at the utilities section as it looks useful.

Actually, the font engine isn’t written yet! The screenshot is just a quick proof-of-concept program (I didn't even change the program title, "Texturing") :D. The idea is for OpenTK to be able to render Unicode glyphs at a decent speed and quality - the actual text layout itself would be best left to more specialized software, like your library. There just are too many scripts and algorithms! (not even operating systems get this topic right all the time)

I’m still pretty new to typography, so forgive me if I’m missing some crucial part of the puzzle. I’d really like to see complex scripts rendered with OpenTK, so I’ll do my best to provide the necessary low-level support and hope that some enterprising user will make this come true (do post a screenshot, please!)

bobbypowers's picture

this sounds great! how are you looking to used managed freetype? I played around with this for a while, but what drove me to wgl is that both in visual studio, when running a program from within the ide (vshost) and when running the application in Parallels on a mac (which, for right now, is unavoidable at times) the glyphs all turned into white square outlines.

I still have the basic c# wrapper I used, and I found what seemed a pretty complete freetype wrapper here, as part of what looked to be a c# port of the supertux game. As this is an issue with the program I'm developing that I have to solve in a week and a half (I'm having issues with WGL bitmap fonts, plus they are slooow to load), if there is a way I could help let me know!

the Fiddler.'s picture

At first, using Freetype seemed unavoidable, however I was not very keen on adding a dependency to an unmanaged dll (it complicates the 'compile once - run everywhere' doctrine), so I searched for an alternative in the managed world. And, indeed, one exists right before our eyes!

I don't know why nobody thought of it before, but the System.Drawing can be used for high quality font rendering. Granted, it doesn't do outline fonts, but it's cross-platform and can be fast with correct caching and texture formats/compression. The screenshot above is the proof-of-concept, and I've since proceeded to implement a texture packer (which can be used to pack 2d items, like font glyphs, into a big texture). Currently, I'm working on the actual glyph renderer. I hope to make the interface generic enough to allow an alternative Freetype implementation in the future.

So far, everything seems to be working. Expect some new screenshots soon!

EDIT: If you need to add text rendering right now, consider using System.Drawing.Graphics.DrawString to draw text onto a Bitmap, and display the Bitmap with a TexSubImage2D call. It will be slow if the text changes every frame, but it will work ok as a quick and dirty solution. I won't be doing this in OpenTK, just something to keep in mind if you have an immediate need.

bobbypowers's picture

great! yes that does seem like a much better solution, I'm gonna start looking at that now. any idea when you'll have a rough working copy up in svn?

the Fiddler.'s picture

I have to finish writing a compiler until this Tuesday so I probably won't have any time till then. I'll probably have something up and running by Thrusday, but no guarantees :)

bobbypowers's picture

haha thats pretty cool :) .net related, or something for school/work?

the Fiddler.'s picture

For school (course on compiler techology). Presenting the mighty PCL Compiler (in Ocaml, too!) :))

bobbypowers's picture

hello there, have you had a chance to look at that text stuff?