After a much shorter development cycle than last time, but longer than I aimed for, here is Alpha6! This release packs a very valuable new feature that affects the whole framework, so read on to know more.

Scaling (Picture by Stephen Edmonds,CC-BY-SA 2.)

UI Scaling

The main feature for this release is UI scaling. WonderGUI now fully supports scaling of the entire UI in increments of 25% (100%, 125% 150%, 175%, 200% and so on). This was my third attempt to add scaling to WonderGUI. My first attempt was badly thought through and abandoned half-way through development when the problems became apparent. My second attempt is currently implemented in WG2 (WonderGUI version 2, which is still maintained and used). It works decently but had a number of drawbacks, most notably an API with duplicate methods for setting/getting geometry in points vs pixels and inconsistencies when converting geometry back and forth between those two units.

With this third attempt I believe I have a solution with an almost seamless API, good performance and minimal problems with inconsistencies during unit conversion. Hopefully it just works for most of you without even giving the relationship of points and pixels any thought.

The magic ingredient is a new primitive called QPix (short for quarter pixels), which keeps the value internally in quarters of a pixel, but seamlessly converts to points when accessing it. I won’t dive into details here, I’ll explain it in a separate blog post when I get the time. For those who want to try it out, you simply create a Context, set its scaling and call wg::Base::setActiveContext().

Currently the scaling is limited to the same scale factor for the whole UI and can’t be dynamically changed at runtime. To change the scale factor you will need to throw away all your widgets, change the scale factor and rebuild the UI. Other components such as Skins, Fonts and TextStyles are not affected and can be kept as they are. These limitations are not inherent to the solution and will be addressed in a future update, but are not prioritized right now.

Also, in case somebody didn’t understand it: This is proper scaling of the UI, not rendering to a backbuffer and then just scaling the bitmap. Fonts and edges remains super clear with no blurring and performance is unaffected by the scale factor.

Improvements to graphics system

There has been several improvements to the graphics system in this release:

BlitSource clipping

SoftGfxDevice has now the intelligence to avoid reading pixels outside the source surface. This makes rotScaleBlit() so much more useful, opening the door to all kinds of widgets and effects where graphics is rotated. Before this you either had to stick to OpenGL rendering or make sure that you had enough pixels between the block to be rotated and the edges of the blit source.

MipMap support (OpenGL only)

GlGfxDevice can now take advantage of mipmaps when scaling down graphics, resulting in better output quality. Mipmapping is enabled on a per-surface basis and needs to be decided when surface is created by setting a flag. The cost is 33% more memory for the surface to hold the mipmaps and degraded performance when unlocking, copying or rendering to the surface. Software rendering ignores this flag.

New blend modes

Two new blend modes have been added: Min and Max. Min results in the lowest value of source and destination for each channel (R, G, B and A) being written. Max is the opposite. These are rarely used but are needed to generate shadows that can overlap each other without artifacts (coming feature).

Alpha only canvas

Alpha-only surfaces can now be used as canvas. There might be many uses for this, but my main goal was to save memory and increase performance when dealing with caching of shadows and vector fonts. For this release though, they both still use 32-bit RGBA surfaces.

Output consistency improvements

A lot of effort has been made to make the output of the OpenGL and software renderer consistent. A few extreme test cases still produce slightly different result, but in most cases the output is identical. I have also noticed some minor variations caused by differences in OpenGL implementation between vendors. But for all practical purposes, the output should now be identical.

New, updated and removed widgets

A ShadowLayer-widget has been created, but was pulled from this release and will be reintroduced later after some refactoring.

The Oscilloscope widget has been removed. It was hardly used and since it will become redundant once I port the much better Chart-widget from WG2, I couldn’t justify the effort to maintain it through the latest round of framework refactorings.

SizeCapsule is currently a work in progress since it was discovered to not handle all situations correctly, but the refactoring work was interrupted. It should work fine for most normal cases, but treat it with some suspicion until the next alpha.

Bugfixes and other minor changes

A few dozen bugs have been fixed all over the place, improving stability, consistency and performance.

So, what’s next?

What will come next is not set in stone. I will adapt my plans to cater to the people who already use and are depending on WonderGUI and they have been hinting about interest in more graphics backends, so that is a hot candidate.

There are also a number of new widgets and features in WG2 that I would like to bring over, and are necessary to eventually migrate current users from WG2.

Anyway, you should expect the next release to contain some new widgets. With most other things in place, a complete set of common base widgets is now what is most lacking in WonderGUI 3. Something I intend to address over the next few releases.