Page 1 of 4

Canvas

Posted: Tue May 13, 2008 4:05 am
by ajs15822
Hey Ogre3D, it's been a while. :D I thought I'd share a little something I've been working on.

What: A super-fast, lightweight, 2D-rendering engine for Ogre3D. To be used for powering simple HUDs or basic interface libraries.

Why: Existing solutions seemed a bit inefficient and I felt like tackling the issue. My implementation is able to batch all rendering into one operation, regardless of document complexity, without using any real-time texture caching.

How: The secret sauce is Atlas, a programmatic texture atlas that can pack font glyphs of multiple fonts and texture assets into a single texture. Assets are pre-loaded into an Atlas, eliminating the need for material-switching in a Canvas (allowing me to get the batch count down to one).


Screenshot: (click for bigger)
Image


Here's a screenshot of the packed Atlas texture that was generated at run-time (in about 0.03s) for the demo. It contains 4 font faces and 5 font sizes (for a total of 500 glyphs) and a single texture (the logo). Please note that most of the unused space is due to POT limitations on texture-sizes. (click for bigger)
Image


The demo itself is also a work of love; everything is data-driven, it can parse "<font></font>" tags (so that you can specify inline font styles), and I also wrote a simple multi-font text-layout implementation (see TextFlowElement).

Download the demo here.


The source is LGPL, non-platform-specific (feel free to port). All you need to build is MSVC8 and the OgreSDK (the only other dependency, FreeType, is included).

Download the source here.


I'm welcome to questions, comments, and critique. :wink:

Posted: Tue May 13, 2008 4:35 am
by NoodlesOnMyBack
Looks really nice! And is exactly what i was looking for, as soon as i test it i'll post a better comment.
Downloading...Woohoo!

Posted: Tue May 13, 2008 6:19 am
by Kojack
hehe, that atlas texture looks almost artistic. :)

Sounds cool.

Posted: Tue May 13, 2008 6:33 am
by Jerky
Very nicely done. Looks fantastic, and the performance is amazing.

Posted: Tue May 13, 2008 6:33 am
by lf3thn4d
Pretty neat. Looking at the atlas, it looks like bsp packing to me. Not very efficient imho, but good enough :)

Posted: Tue May 13, 2008 12:25 pm
by AshMcConnell
Fantastic, this will help me quite a bit for making a HUD. Thanks!

Is it suitable for quickly changing stuff (e.g. Laptime / Speed / RPM etc?)

Thanks again!
Ash

PS. Just tested the demo and it ran at ~5000fps (yes FIVE thousand!)

Posted: Tue May 13, 2008 12:42 pm
by betajaen
Oh my.

I have to use this in something.

Posted: Tue May 13, 2008 1:44 pm
by pratty70
Oh my.

I have to use this in something.
ditto!

Just got to add to this - totally awesome - what superb performance!! Nice job.

Posted: Tue May 13, 2008 1:58 pm
by ValentinGalea
I for one, welcome our new overlord Atlas!

Posted: Tue May 13, 2008 3:40 pm
by Praetor
Very awesome.

Posted: Tue May 13, 2008 5:18 pm
by ajs15822
Kojack wrote:hehe, that atlas texture looks almost artistic. :)
Heh, you're right-- it looks like an experiment in typography. :P
lf3thn4d wrote:Pretty neat. Looking at the atlas, it looks like bsp packing to me. Not very efficient imho, but good enough
Yup, the packing algo is binary space partitioning-- I needed something that could balance results with performance. If you have any suggestions for better algorithms to try, please share! :)
AshMcConnell wrote:Is it suitable for quickly changing stuff
Absolutely, it was designed for frequent geometry updates.

Similar to Ogre's BillboardSet, Canvas keeps a pool of quads around and resizes the index/vertex buffers only when it needs to. Confining the rendering to indexed quads allows us to decrease the number of vertices required (speeding up vertex buffer updates) and also to optimize index buffer updates (it is only updated during buffer resize).
AshMcConnell wrote:PS. Just tested the demo and it ran at ~5000fps (yes FIVE thousand!)
Hawt :P
ValentinGalea wrote:I for one, welcome our new overlord Atlas!
Rofl.

Posted: Tue May 13, 2008 5:35 pm
by Kentamanos
Nicely done :).

Posted: Tue May 13, 2008 6:17 pm
by Frenetic
I downloaded it and gave it a quick look, and I must say, holy shit, this looks excellent! Elegant, well documented... This might save me a lot of time...

Thank you, thank you! :D

Posted: Tue May 13, 2008 6:43 pm
by sinbad
Very nice work indeed. Thanks for sharing!

Posted: Tue May 13, 2008 7:08 pm
by Frenetic
Say, what happens when the Atlas gets too big? Looking at the source, it seems the Atlas expands infinitely, whereas I think most current cards only support 2048x2048 textures, the newer fancier ones do 4096, and older or on-board ones can only do 1024. Also, some on-board cards don't like large non-square (eg. 512x1024) textures... so a feature for general texture-size constraints, maybe an error-check or something, would be nice. And maybe the ability to "reserve()" a certain size ala std::vector.

I suppose I can use several Canvas+Atlases if I expect to be using a crap-ton of textures? I'll probably replace my own GUI-drawing code with this (improving my own code would be re-inventing the wheel now) and I have lots of fonts and text, lots of background images, lots of icons, etc. so going beyond the max texture size my card supports is almost certain.

Oh, and the fonts in my app are (supposed to be) user-customizable. Dynamically regenerating the fonts shouldn't be too hard, right? (This feature does not need real-time performance, of course)

Lastly, it bugs me that you don't use the mWhatever member-variable convention... everything else is so far above my highest standards, that this tiny issue stands out... ;)

Posted: Tue May 13, 2008 8:12 pm
by detox
thank you for sharing the source. I will definitely be using this.

Posted: Tue May 13, 2008 8:51 pm
by metaldev
wow if i switch from navi now i can use my own fonts ^_^


so happy :o ajs, my hero.

Posted: Tue May 13, 2008 10:20 pm
by pratty70
I think this is so good - and so very useful it warrants a second reply!! Many many many thanks for this, I know it's gonna prove so useful for us!

Still keep having to run the demo to realise just how impressive this is!

Posted: Wed May 14, 2008 2:20 am
by neocryptek
betajaen wrote:Oh my.

I have to use this in something.
Ditto...

Thanks a lot for sharing!

Linux port

Posted: Wed May 14, 2008 5:07 am
by Fuinelen
First of all, thanks a lot for sharing :)

I'm trying to port it to linux right now (using code::blocks) and I got so far as to only receive this lonely error :

Code: Select all

Canvas - May 12th 2008/Canvas/Source/Atlas.cpp||In member function ‘void Atlas::pack(ComputationVector&)’:|
Canvas - May 12th 2008/Canvas/Source/Atlas.cpp|385|error: no matching function for call to ‘sort(__gnu_cxx::__normal_iterator<ComputationRect**, std::vector<ComputationRect*, std::allocator<ComputationRect*> > >, __gnu_cxx::__normal_iterator<ComputationRect**, std::vector<ComputationRect*, std::allocator<ComputationRect*> > >, Atlas::pack(ComputationVector&)::compare)’|
any ideas what I missed?

Posted: Wed May 14, 2008 11:49 am
by scriptkid
Hey there,

looks nice :) I browsed through the code and liked your apprauch of using states for painting formatted text.

As you mention, you wrote it to power simple HUD elements. Does that mean that users should combine your system with a more full-blown system in order to create an options screen or an inventory, for example? Or are you going to add more widget types?

Good luck anyway :)

Posted: Wed May 14, 2008 12:44 pm
by Lord LoriK
Wow, ajs15822! Very good job. Well done, as always.

Suggestions:
* I think quite a lot of the "demo" source should go into the main library. The Document, Element, ImageElement, Parser and TextFlowElement feel like "core" classes, IMO.

* Add text justification to TextFlowElement.

* Add serialization support. Creating an editor with that would be a piece of cake.

* Multitexture support. Even if this increases the batch count, is the only way to provide nearly limitless flexibility.

* AnimatedImageElement. 'Nuff said.

* Primitive drawing: point, line, circle, square, polyline. Maybe a fill function, too.

I had to reinstall my system a few days ago, but if I manage to set my development environment soon enough, I'll gladly help with these.

Posted: Wed May 14, 2008 2:13 pm
by Nauk
Very usefull AJ, good work there :)

Posted: Wed May 14, 2008 3:54 pm
by gamedboy
This is very cool, Great Job!

Posted: Wed May 14, 2008 4:55 pm
by nikki
Wonderful stuff there! But don't you think some of the things in the demo should actually be part of the library itself? Or is your library supposed to be confined to just image loading only?