Skip to main content
gamedev.net
🔒 Locked

Font Rendering, 2D path, Performance

Started by Robert Frunzke 3 replies 850+ views
Original Post
Robert Frunzke
Robert Frunzke
The font renderer (freetype) produces 8bit pixmaps. Those should be drawn as antialiased pixmaps using some nice blending onto the background, so I use drawpixels() with format=GL_ALPHA to draw them. Putting glDrawPixels in a display list greatly improves performance. The problem now is, how to make it possible to render the pixmaps using alpha blending and setting a different "font color" than "black"? Solution was to use glPixelTransfer with GL_xxx_BIAS (RED,GREEN and BLUE bias set to the target color and ALPHA_SCALE to set alpha). This makes the code a perfect fit to my application. BUT bias and scale make rendering text very slow (e.g. 250fps with bias and scale, and >999fps without for a 200x300 pixmap with text). Putting the transfer options into the display list did not help. Is there a better way, to draw a single-channel pixmap and still set the color? drawpixels() with GL_ALPHA unfortunatly sets the color to (0,0,0), and ignores the glColor() setting. When using GL_LUMINANCE one can set the color, but will loose the alpha channel. Also I can not see any glBlendFunc() variation to get the required flexibility.
_the_phantom_
_the_phantom_
Upload it to a texture and render it on a quad instead. This method should be fast enuff if you cache the texture between changes to the text, only updating it when the text changes.
Robert Frunzke
Robert Frunzke

The final application may have a lot of small text snippets - besides or on top of user interface elements.

My first implementation was based on the texture+quad method. But required too much overhead and was in fact even slower.

E.g. for backward compatibility one has to make texture size a power of two - newer cards can ignore this. Solving this problem ended in even slower performance than the current solution. Different solutions where either slow or looked bad.


_the_phantom_
_the_phantom_
Unless you are doing something very wrong I can't see how it would be slower to a noticable degree.

I wrote a system in 2005 using Freetype which updated two textures (sized to power of two); one for FPS and one for updates per second textures. That, rendered via two quads, plus 8 cubes on screen (all drawn in immediate mode) took ~0.5ms per frame (hitting well over 1000fps). This code wasn't even optimised and suffered numberous problems.

As for the various size issues; you can pack fonts into textures so more than one string is in a texture if you need it. However this might be a problem with non-static strings which you can't determine the max lenght for.
Robert Frunzke
Robert Frunzke
Ok thanks. I'll give it another try.

No idea yet, how to pack more than one text snippet into a texture.

There are some objects involved:

FontRenderer : creates memory pixmap from text
Texture
OverlayEntity : can contain a texture or a pixmap, and handles all the 2D path items (GUI element fragments and Texts)
GUIEntity : manages overlayentities

Currently the GUIEntity draws the text on a memory bitmap, and creates an overlayentity that does the rest.

Other elements (e.g. topleft, topright button corners) are in a single texture atlas and will be drawn using multiple overlayentities that share the same texture.

GUIElement could easily create a texture from the text and give that to the OverlayEntity.

I could try to add an AutomaticAtlasTexture object or something similar.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.