IrrlichtML CGUITTFont addition..

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

IrrlichtML CGUITTFont addition..

Post by archilife »

I recently found out the IrrlichtML project is still continuosly
updating to the newest Irrlicht version, I am so happy :D

http://etwas.wolfish.org/Irrlicht/irrlichtml_en.html

In my project I used their code to pump out font textures which can
be used on a simple plane in 3D, so I can make those text scale, rotate,
moving and changing color blending the way like I would do to any other
scene nodes. But in their newest update I found out that the code base
changed too much in the last year, so I have to rewrite my code too.

Basically I have no knowledge about FreeType lib usage, so I just
mimic what they did in the CGUITTFont::draw() method, just instead of
calling driver->Draw2DImage, I setup planes and scene nodes and return
them in a method called CGUITFont::addTextSceneNode()

There's a little naming differences between my code snippet below
and the original IrrlichtML's CGUITTFont and I actually did some
refactoring (added IGUITTFont interface which extends IGUIFont).
I hold no warranty of this code, use this at your own risk.

*UPDATE*
The original code here was removed. please checkout my git repository,
although it is still a mess..

http://github.com/arch-jslin/Irrlicht/b ... UITTFont.h
http://github.com/arch-jslin/Irrlicht/b ... UITTFont.h
http://github.com/arch-jslin/Irrlicht/b ... TTFont.cpp

and possibly
http://github.com/arch-jslin/Irrlicht/b ... onment.cpp
about the addFont part.

New screenies:

Image

Image
Last edited by archilife on Thu Mar 17, 2011 9:09 am, edited 4 times in total.
Nalin
Posts: 194
Joined: Thu Mar 30, 2006 12:34 am
Location: Lacey, WA, USA
Contact:

Post by Nalin »

That is pretty cool. Unfortunately, if IrrlichtML decides to update to my latest version of CGUITTFont, your code will completely break, so watch out for that. My new version sticks all the font textures into a single texture atlas and batches all the draw calls.
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

Post by archilife »

Thanks to warn in advance :)

Just a little question though, how do you manage to stick all
font textures into a single texture atlas if that font has like
, say more than a few thousands or even tens of thousands glyphs?
Because that's the nature of multi-byte languages,
if you just stick them all together, but in the user program
they might not be using all the glyphs. Won't that be a little
wasteful on resources? If I missed something please do tell me.

btw, may I have a link to your code? so I can determine how
many of my codes may be revised. Thanks a lot :)
Nalin
Posts: 194
Joined: Thu Mar 30, 2006 12:34 am
Location: Lacey, WA, USA
Contact:

Post by Nalin »

archilife wrote:Thanks to warn in advance :)

Just a little question though, how do you manage to stick all
font textures into a single texture atlas if that font has like
, say more than a few thousands or even tens of thousands glyphs?
Because that's the nature of multi-byte languages,
if you just stick them all together, but in the user program
they might not be using all the glyphs. Won't that be a little
wasteful on resources? If I missed something please do tell me.

btw, may I have a link to your code? so I can determine how
many of my codes may be revised. Thanks a lot :)
My code can be found in this thread:
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=37296

What I do is create a texture large enough to hold at least 400 glyphs, then cap the texture to the maximum texture size for your hardware. I then preload the basic ASCII characters. If you try to draw a glyph that hasn't been cached, it will load that glyph and the surrounding glyphs into the texture. If the texture fills up and there are no more free glyphs, the system will create a new texture and start to fill that one up too. When it draws your text, it will determine which textures to use, then batch draw all the glyphs for each texture. It is more complex than the old method, but it gives a nice frames/second boost.
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

Post by archilife »

That's definitely extraordinary! :)

After a first glimpse into the new code base, I figured the
code structure hasn't changed much, so I think I can live with
that.

I see now the newly added GlyphPage structure holds the
video::ITexture, so I think mainly I just have to change how my
planes get their corresponding glyph textures. Some uv coords
adjustments will do the work I guess. I'll catch up with your
version as soon as IrrlichtML update CGUITTFont to your code.

Thanks again for your timely explanation, taught me a lot :)
MadHyde
Posts: 34
Joined: Thu Sep 28, 2006 9:46 pm
Location: Japan
Contact:

Post by MadHyde »

Oh.. I noticed your post now.

I just uploaded IrrlichtML with newer CGUITTFont.
http://irrlicht.sourceforge.net/phpBB2/ ... 3&start=53
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

Post by archilife »

Ok, I'll update my code accordingly as soon as possible. :)

Thanks again!
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

Post by archilife »

I've just tried to apply paging method to my addTextSceneNode
function, the FPS boost is very significant :)

But I'm still figuring out the abnormal memory usage after
I apply this method, and doing some code clean-up as well,
I'll update my original post as soon as possible.
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

Post by archilife »

I am still in the process of reducing memory usage of this new method,
already cut the memory usage in half. The CGUITTGlyphPage now holds
only video::ITexture; video::IImage is dropped. Each SGUITTGlyph holds
a video::IImage of its own glyph bitmap again; however, when the
page->updateTexture() is called, all of the individual bitmap will be
paged accordingly and dropped afterwards. CGUITTFont::draw() remains
unchanged. There's still many code sections and comments need to be
cleaned up, if anyone is interested right away please check out:

http://github.com/arch-jslin/Irrlicht/b ... UITTFont.h
http://github.com/arch-jslin/Irrlicht/b ... UITTFont.h
http://github.com/arch-jslin/Irrlicht/b ... TTFont.cpp

and possibly
http://github.com/arch-jslin/Irrlicht/b ... onment.cpp
about the addFont part.

And I am actually up to reduce the memory usage even further to
one-fourth from now. Because the bitmap we load from FT_Library are
either monochrome or grayscale only, assign them to a A1R5G5B5 or
A8R8G8B8 texture is pretty wasting. Consider a 2048x2048x32bit
texture, that's 16MB already!

I'm not sure if it is even doable or not, because that require a
texture structure that support grayscale(8bit) texture, by doing that
we also need a specific material renderer that will use grayscale
texture (in OpenGL there is GL_LUMINANCE flag which can set texture
flag to grayscale, I don't know about D3D though.), but I am not sure
if I use something like GL_LUMINANCE, can I still do the color
blending?

Beside the loading process, I did change some very subtle thing but it
will affect the performance quite much. I think the page size should
be reduced in general, in order to get a better balance between memory
usage and frames per second performance. I set the page size to
256x256 only if the font size is less than or equal to 21,
512x512 <-> 42 ... and the like. so every page holds like 144 glyphs
or so. The reason is that if you use TrueType font but only the ASCII
character part, it'll be less wasteful; and even if you use many
unicode characters, it still somewhat retains the performance boost.

Another suggestion is: don't use batch load, (i.e. set it to 1 only)
except for the initial batch load. (the first 127 ASCII characters.)

Two reasons for this:

First, there's little difference between cache 1 character a time or
cache a batch which contains tens or hundreds of characters. Because
the real threshold happens when you load glyph and allocate memory for
them. As long as we do it exactly only once for each glyph, and only
calls page->updateTexture() once at most for each call to
font->draw(), the differences between two methods are virtually
unnoticable.

Second, I tried batch loading 128 glyphs a time with chinese
characters, the test case is displaying a chinese news article around
100 ~ 200 words. It resulted in a noticable stutter and the memory
usage bloated, loading more than 4000 glyphs all of a sudden. I think
the cache miss rate of the batch loading method is too high.

All suggestion are welcomed, thanks in advance :)

Sincerely.
Last edited by archilife on Thu Mar 17, 2011 9:10 am, edited 2 times in total.
Nalin
Posts: 194
Joined: Thu Mar 30, 2006 12:34 am
Location: Lacey, WA, USA
Contact:

Post by Nalin »

Wow, that is some nice work. Do you mind if I integrate your changes with the version I maintain?
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

Post by archilife »

By all means :)

I did add some comments on critical parts of my changes,
but maybe not all of them are well-commented. In case of
confusion, please let me know. :)
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

Post by archilife »

Load 8-bit grayscale texture with OpenGL is pretty easy,
I've tested it with NeHe's OpenGL Tutorial code. But to my
dismay, Direct3D9 just doesn't support that. The most compact
format both drivers have in common is A1R5G5B5.

Even if there's any possibility to make this work on both
drivers, it would be too hacky. On the other hand, add a new
value to ECOLOR_FORMAT is too fundamental and extensive for a
change not to be able to go across the platforms.

The last resort might be packing 4 8bit grayscale textures
into the four channels of a 32bit texture and then somehow
extract the data using shaders when drawing. However, I know
little about shaders. So, uh, I must give up for now. Maybe
I'll pick this up again after I learn some shaders. :)
vroad
Posts: 18
Joined: Sun Jan 03, 2010 1:30 pm

Memory leak in CGUITTFont

Post by vroad »

Hi
I'm using CGUITTFont from your git repository.
I founded a memory leak and tried to fix it.

http://pastebin.com/dHupSHAc

I think Direct3D9 supports 8bit alpha-only or luminance-only formats. (D3DFMT_A8, D3DFMT_L8)
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

Post by archilife »

I must apologize, I've been busy working on the day job
and didn't see your post..

and .. wow, thanks for the fix, I'll look into it ASAP! :D

about the 8bit thingy, thanks for pointing out, as I was
not familiar with Direct3D programming. However, I'm afraid
that I will not be able to dig into this issue in the near
future because of my day job. If someone has ideas about how
to make Irrlicht support luminance/alpha only texture and has
time to implement it, please do consider merging it with
IrrlichtML branch.

Best regards.

:)
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

Post by archilife »

According to the working flow of corresponding methods and classes,
the leakage should be pretty unlikely, but I've corrected the code
nonetheless, thanks vroad!

I only patched the main 'cubeat-irrlicht' branch in my repository,
so if anyone else happens to be interested in this, please make sure
you pull the right branch.

btw, Paulus seemed to have stopped updating his fork of Irrlicht,
from which my fork originated. I'll try to update my repository if
the official Irrlicht gets a major update. If I have time to update
my repo... that is.

Best regards. :)
Post Reply