armory3d/zui

Text Rendering Issues

Closed this issue · 5 comments

I was thinking of going back to using Zui and perhaps contributing some major changes to make it more "complete" so that I may use it as part of a project I am working on. However, I have found a crucial issue with regards to text rendering.

In certain contexts, text rendering appears to be smooth and anti-aliased as expected, and in other contexts not.

I decided to create a simple example comparing a simple drawString call directly from g2 context and one from zui context:

g2.font = Assets.fonts.MavenPro_Regular;
g2.fontSize = 20;
g2.color = Color.Black;
g2.drawString("This is some text.", 100, 300);


ui.begin(g2);

if (ui.window(Id.handle(), 10, 10, 500, 120))
{
	ui.row([0.2, 0.5, 0.3]);
	ui.text("Module:", Right);
	ui.combo(Id.handle(), ["Human Resources"]);
}

ui.end();

To try to replicate as much as possible, I have also adjusted the font size in the light theme and changed all text colour values to black.

This is the result:

image

The text at the bottom is directly rendered from g2 context, which is exactly what I would expect to see when using zui context. Strangely, the combo box contents are fine:

image

I have taken a look behind the scenes and it appears that whenever drawString is called, there are times when globalG.begin() is called, with it's relevant end() call, and other times neither is called, like inside the text() call context, which is likely the reason for this unusual text rendering behaviour. This, in my opinion, could be easily fixed by refactoring all the draw calls within a single begin() and end() wrapper and there would be no need for all these begin() and end() wrappers floating aimlessly in the code base.

For background fills on the window, for example, these could simply be fillRect() calls directly from the g variable.

I will happily fix this issue, but I was wondering firstly if there was a good reason to have a globalG variable.

globalG should only be called for things floating above, like tooltips or opened combo list. Everything else is cached into window texture to save resources, which is done in a single begin/end call. I will check whether drawing text into render target causes the difference.

So in other words a background buffer is used? It could be better to use Image with Image.createRenderTarget for that purpose which I suspect will fix this particular text rendering issue.

Or is that actually being done? It's been a while since I looked at the codebase or any of the changes.

The window cache is allocated using Image.createRenderTarget. globalG is a graphics2 object passed into ui.begin (either from kha.Framebuffer or kha.Image). Nonetheless drawing should produce the same result. The difference may also come in when window cache is drawn using globalG. But will do some actual testing..

Could you test #86 and see if that improves text rendering for you?

I've just tested. The text rendering looks good now.

Result:

image

I have had to change the tint colour for the light theme because it didn't look right to me. Originally, the tint colour is 0xff222222 which creates a dark background colour which doesn't make sense for a theme that's meant to be light!