haymo's picture

Multiple Font objects

I experience strange behavior with TextureFont and TextRenderer: TextureFont seems to shuffle the glyph <-> char mapping _sometimes_ :(
Steps to reproduce the behavior:

Call the following snippet more than 15 times - once per rendering frame. Every time 'text' should be only one char. Each char should be different.

 //... other rendering stuff
TextHandle handle; 
m_textPrinter.Prepare(text,m_font,out handle);
m_textPrinter.Begin();
using (handle) 
    m_textPrinter.Draw(handle); 
m_textPrinter.End();
//...finish other rendering stuff + swapbuffers

Once 15 chars are loaded into the font, the output gets scrambled, ie. where "a" should be - is now "5" or something completely different, even blank space. It is not deterministic, what is drawn instead. But it is deterministic, that a false texture is drawn.

Also, the bahavior does not happen, when loading more than 15 chars at once, but only by incrementally loading the chars in the way shown above.

Dont know if '15' is specific to my machine either.


Comments

Comment viewing options

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

Actually, both algorithms are generic and don't rely on .Net or GL.

If my understanding is correct, the best candidate for unit tests is OpenTK.Math. Besides that and OpenTK.Fonts, there are a few other suitable candidates, but unfortunately the bulk of OpenTK is low-level code (window creation etc) and I don't think this can be verified with unit tests (unless I'm wrong?)

I'll be reading up on unit testing, it looks like a very useful skill/tool.

objarni's picture

Yup, I think those are the best candidates right now. Therefore, those two have the potential of being the most "stable" things in OpenTK.

I discovered unit testing a little more than a year ago, and it has been a paradigm shift in the way that I do software development. Good luck and please share your experiences! I'm still learning, it's a huge topic.

Testing wrapping functionality should not be necessary, if it's a thin enough wrapper, which I think GL is for the most part.

The windowing code is the toughest part. Keeping it as small as possible, and writing lots of examples to be run "manually" is a good beginning.

haymo's picture

... thinking about this Font rendering stuff again:

Storage:
Taking Fiddler's considerations above in account, I agree with you, to have one single storage texture for all Fonts involved. This would (at least in all situations I can think of right now) be a texture sheet, loaded up into the GL and used for all subsequent renderings - no matter wich font currently is targeted.

** Are there any needs to keep the implementation for the storage (TextureFont) abstract? My concern is, that the way, the glyphs are stored will highly influence the way the printer works. Therefore, it does not seem to make sence to implement them seperately ?!? Or the printer may be created via a factory by TextureFont. Personally I would expect the increase in flexibility for an abstract TextureFont implementation not paying off the increase in complexity and the (possible?) decrease in performance. Therefore, I suggest to fix the TextureFont (storage) in a concrete class at the root of the whole Font implementation. That implementation would ALWAYS store the glyphs as texture sheets - its it.

** As soon as a sheet gets filled and needs more space for new glyphs, question arises, which strategy to choose:
i) replace the existing texture sheet by a larger one (f.e. twice as large, if possible) and copy all existing glyphs, possibly compacting the glyphs at the same time, or
ii) create and manage multiple sheets at the same time. This attempt IMO is better regarding memory consumption and (card) compatibility, but worse regarding the original design decisions (texture switching).
Both attempts come with the drawback of having to handle the case, the requested size for the sheets beeing too large for the memory avaliable.
Any comments on this?

** In order to store and manage glyphs from multiple fonts on the same texture sheet, we need a way to hash-map a glyph. For this, the information, which System.Font the character belongs to must be taken into account also. Right now this is solved by having TextureFont objects for each font individually - all share the same global texture sheet. But there are some drawbacks for this design too:
i) if a TextureFont is destroyed, it leaves its Glyphs in the sheet. We would have to clean / recompact the texture sheet in such a case (or did I miss this part in the code?)
ii) multiple TextureFonts could be created, based on the same System.Font. Possibly this would result in multiple identical glyphs in the sheet.
My favorite is to have only one singleton implementation of texture storage (TexturePacker?) also managing all Fonts it currently stores the Glyphs for. Right now I'm seeking the best way to identify a FontFamily-Name-Size-Weight-(...?)-Character combination uniquely.??

Printers
** Am I right, thinking that the printer implementation is the only part which should be flexible enough and implemented via interfaces/ abstract base classes (my favorite)? This part I haven't thought about a lot yet. But it seems the current implementations are pretty straight forward and already pointing in the best direction here ...?

Hope, my understanding is not going in the complete wrong direction on this... thanks.