Font rendering system overhaul
Moderator: Moderators
Font rendering system overhaul
As announced in another thread, I have now rewritten the font rendering system used in Spring. My version renders all glyphs into one texture instead of using one texture per glyph, and I have ditched display lists, which actually seems to be faster because:
1. When using DLs, we can not group multiple glyphs into one glBegin/End pair because glTranslatef can not go between such a pair.
2. We can now eliminate all glPushMatrix/PopMatrix pairs related to font rendering because the transformations are calculated on the fly.
3. There is a certain overhead to using DLs, and having one quad per DL is probably not efficient.
Also, I have introduced a second smaller font for small UI elements.
Unfortunately, it wasn't as easy as I thought because there was virtually no encapsulation of font rendering: every piece of code which had to draw a string seemed to handle it differently. In effect, I had to patch up virtually all such places. On the plus side, this code is much cleaner now as I have tried to factor all common stuff into the CglFont class.
On my machine (Athlon XP 3200, Radeon 9500), this patch gives a nice framerate boost at the start of the game, i.e. when idling. It probably doesn't make much difference later when lots of other stuff is going on, but I think the cleaner code alone is well worth it.
As an aside, I have also slightly reformatted the resource bar to make it better legible. I think it's much better now.
On the whole, there are some slight differences in rendering introduced from the last version, but nothing seems to have degraded noticeably in quality.
This is my first contribution to Spring. I am attaching the patch to this post. Should I also put it on Mantis, or is it okay here? In any case, would be great if someone could try it and incorporate it into SVN if everything's alright. I already have ideas for other optimizations...
1. When using DLs, we can not group multiple glyphs into one glBegin/End pair because glTranslatef can not go between such a pair.
2. We can now eliminate all glPushMatrix/PopMatrix pairs related to font rendering because the transformations are calculated on the fly.
3. There is a certain overhead to using DLs, and having one quad per DL is probably not efficient.
Also, I have introduced a second smaller font for small UI elements.
Unfortunately, it wasn't as easy as I thought because there was virtually no encapsulation of font rendering: every piece of code which had to draw a string seemed to handle it differently. In effect, I had to patch up virtually all such places. On the plus side, this code is much cleaner now as I have tried to factor all common stuff into the CglFont class.
On my machine (Athlon XP 3200, Radeon 9500), this patch gives a nice framerate boost at the start of the game, i.e. when idling. It probably doesn't make much difference later when lots of other stuff is going on, but I think the cleaner code alone is well worth it.
As an aside, I have also slightly reformatted the resource bar to make it better legible. I think it's much better now.
On the whole, there are some slight differences in rendering introduced from the last version, but nothing seems to have degraded noticeably in quality.
This is my first contribution to Spring. I am attaching the patch to this post. Should I also put it on Mantis, or is it okay here? In any case, would be great if someone could try it and incorporate it into SVN if everything's alright. I already have ideas for other optimizations...
- Attachments
-
- spring_font_rendering.zip
- (18.35 KiB) Downloaded 43 times
-
- Spring Developer
- Posts: 1254
- Joined: 24 Jun 2007, 08:34
Re: Font rendering system overhaul
Nice, but
I think its not usefull to throw pointers to std::runtime_errors 
Code: Select all
terminate called after throwing an instance of 'std::runtime_error*'

Re: Font rendering system overhaul
A java/C#-ism 
Either way I get that too.
It's this part that is throwing, line 97 in glFont.cpp:

Either way I get that too.
It's this part that is throwing, line 97 in glFont.cpp:
Code: Select all
if (curY >= height)
throw new std::runtime_error("CFontTextureRenderer: buffer not high enough");
Code wise it looks good tho, didn't spot anything yet besides that ^^.#7 0x08073a4a in CFontTextureRenderer::BreakLine (this=0xbfa36778) at rts/Rendering/glFont.cpp:97
#8 0x08073bc1 in CFontTextureRenderer::AddGlyph (this=0xbfa36778, slot=0x8857140, outX=@0xbfa3679c, outY=@0xbfa36798) at rts/Rendering/glFont.cpp:68
#9 0x08074396 in CglFont (this=0x8851d80, start=32, end=223, fontfile=0x879d8fc "Luxi.ttf", size=0.0270000007, texWidth=128, texHeight=128)
at rts/Rendering/glFont.cpp:192
#10 0x080749aa in CglFont::TryConstructFont (fontFile=@0xbfa36874, start=32, end=223, size=0.0270000007) at rts/Rendering/glFont.cpp:238
#11 0x080fae86 in SpringApp::Initialize (this=0xbfa36944) at rts/System/Main.cpp:344
#12 0x080fbaa8 in SpringApp::Run (this=0xbfa36944, argc=1, argv=0xbfa36a34) at rts/System/Main.cpp:930
Re: Font rendering system overhaul
Sounds like a much needed patch. Maybe with the implemented, luaUI could be turned on by default. :D
- BrainDamage
- Lobby Developer
- Posts: 1164
- Joined: 25 Sep 2006, 13:56
Re: Font rendering system overhaul
it is already since 0.76b1LordMatt wrote:Sounds like a much needed patch. Maybe with the implemented, luaUI could be turned on by default. :D
Re: Font rendering system overhaul
Well maybe IceUI could be included by default then. 

Re: Font rendering system overhaul
Sorry 'bout that exception thing, indeed I use C# at work and my C++ is a bit rusty 
But actually I thought I replaced that exception with a custom one, let me look again...
EDIT: Yes, I fixed the two other places to use a texture_size_exception, but I forgot about this place.

But actually I thought I replaced that exception with a custom one, let me look again...
EDIT: Yes, I fixed the two other places to use a texture_size_exception, but I forgot about this place.
Re: Font rendering system overhaul
Any clue why the exception was thrown btw, do we need to change a setting or move a font file around or something? Atm Spring is unrunnable for me with your patch applied.
(looks a bit like an assertion exception, ie. some internal error?)
(looks a bit like an assertion exception, ie. some internal error?)
Re: Font rendering system overhaul
That exception serves as a check for texture size.... we start with an 128x128 texture and enlarge it by a factor of 2 every time we fail to pack all glyphs into it. It's a bit inelegant, but there is simply no way to predict in advance how large a texture the font will require.Tobi wrote:Any clue why the exception was thrown btw, do we need to change a setting or move a font file around or something? Atm Spring is unrunnable for me with your patch applied.
(looks a bit like an assertion exception, ie. some internal error?)
In any case, this piece of code:
Code: Select all
+ if (curY >= height)
+ throw new std::runtime_error("CFontTextureRenderer: buffer not high enough");
Code: Select all
+ if (curY >= height)
+ throw texture_size_exception();
Re: Font rendering system overhaul
Bump. I'm uploading a fixed version of the patch, against the latest SVN source. Please retry.
- Attachments
-
- spring_font_rendering2.zip
- (18.33 KiB) Downloaded 34 times
Re: Font rendering system overhaul
Bump. Not to sound impatient or anything, but what's the chance of getting this merged into SVN? I'd really like to look at ground decal rendering next, but only if my time isn't spent in vain.
Re: Font rendering system overhaul
Chances are good, I just don't really have time until after the weekend.
Re: Font rendering system overhaul
Ah, thanks. Just wanted to make sure it wasn't forgotten about.
Re: Font rendering system overhaul
Second patch compiles fine and runs fine, but I think it messes up outlined fonts. Try enabling the 'Eyes' widget for example. Could you take a look and see if the effect is indeed a bug in your patch?
ResourceBar and other ingame fonts are all good though.
ResourceBar and other ingame fonts are all good though.
Re: Font rendering system overhaul
I can reproduce that, yes. It's the result of Eyes doing something very non-standard with text output (custom GL matrix transformations). I don't think any other widget has a need for that, or have you noticed the problem anywhere else? I'm attaching a screenshot: note that many UI elements use outlined fonts, e.g. the game time clock and the info console. All those work fine.Tobi wrote:Second patch compiles fine and runs fine, but I think it messes up outlined fonts. Try enabling the 'Eyes' widget for example. Could you take a look and see if the effect is indeed a bug in your patch?
To explain what's going wrong: Outlined text is drawn by first rendering four copies of the text in black offset by (-1,-1), (-1,1), (1,-1), and (1,1) in pixels. Then the real glyph is drawn over that. I took that logic more or less from the old text renderer so far. Now if you do some funky matrix manipulation, you no longer have any idea how far 1 pixel is in viewport coordinates, and hence this kind of stuff happens. This might also be related to the problem that, while Spring internally uses [0,1]x[0,1] for viewport coordinates, the Lua API inexplicably uses real pixel coordinates, and I had to work around that.
One possible fix would be to render a separate texture for outlined glyphs, with the outlining already baked into the texture. I could do that as a follow-up patch, if desired; should also speed up outlined font rendering a lot since we would only need to render 1 quad instead of 5 per glyph.
Also, if any mod or widget writer has any needs for such non-standard stuff, I would gladly work together with them to work out an interface for such tasks. Eyes however doesn't qualify because of course nobody uses that ugly thing.
There's an other thing: you might have noticed that in-world outlined text has never really worked (not only since my patch). This is on display in Fibre, and also in E&E when upgrading buildings or units: for text that is rendered "in-world" next to units, you get these unsightly black borders whose size doesn't match up with the text size. I'm attaching another screenshot (taken in 0.76b1) to illustrate this. Once my patch is accepted, the infrastructure is in place to tackle this; the only reason I haven't fixed this so far is that it will most likely require slight changes on the Lua side, so I'd have to talk to the modders.
So, to summarize: I don't consider this a bug in the patch, but failure due to bad interface design and encapsulation (Lua-side raw GL operations in order to render text). If the problem occurs only in Eyes, I don't consider this grounds to reject the patch. I will work with interested scripters to further improve the situation in special cases.
- Attachments
-
- fibre-outlined.jpg
- (149.42 KiB) Downloaded 114 times
-
- screen005.jpg
- (193.76 KiB) Downloaded 115 times
Re: Font rendering system overhaul
Any news of this? has this been comitted yet?
Re: Font rendering system overhaul
I thought it already had been. I guess not. 

Re: Font rendering system overhaul
So, eh, still nothing?
Re: Font rendering system overhaul
Committed, thank you eriatarka for your contribution (and sorry for the extreme slowness
)

- clumsy_culhane
- Posts: 370
- Joined: 30 Jul 2007, 10:27
Re: Font rendering system overhaul
phwhoa that was sloww . Nice work tho.. in layman (fps) terms , what kind of perfomance increase/decrease will i see?