Text rendering quality

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Text rendering quality

Marian Schedenig
I'm struggling with getting decent text rendering in my JOGL game. I originally wrote my GL code as Android native GL2ES code before porting it to JOGL for the desktop version. The Android code uses Android's own graphics library to render text strings to a texture and then display them via GL, but with JOGL I'm trying to rely on its own TextRenderer functionality instead of reinventing the wheel. Most of the remaining code is still pretty much the same it was on Android, so I'm using standard GL calls most of the time and JOGL specific classes only in a few instance, e.g. when setting up the GLWindow.

Most of my text rendering occurs in my GUI classes, where each frame is rendered onto a framebuffer texture (created without any JOGL specific code) and then from there onto the main screen. I'm using my own primitive vertex and fragment shaders and the curve based TextRenderer seems to work well enough with those.

This is my initialisation code:

public TextRenderer getTextRenderer()
{
        if(textRenderer == null)
        {
                ShaderState ss = new ShaderState();
                RenderState rs = RenderState.createRenderState(ss, SVertex.factory());
                int renderModes = GLRegion.VBAA_RENDERING_BIT;
                textRenderer = TextRenderer.create(rs, renderModes);
                textRenderer.init(gl);
        }
       
        return textRenderer;
}

And here's how I render a text string, after setting up my shader's matrix correctly (which is why I always pass 0/0 as the coordinates):

getTextRenderer().drawString3D(gl, glFont.getFont(), text.getText(), new float[]{0, 0}, (int) glFont.getSize(), new int[]{0});

Problem is, the quality is rather lousy, as you can see in this image:



The FPS display on the upper right is drawn directly on the screen and thus takes advantage of my GLWindow's sample buffer settings (caps.setNumSamples(4)). It doesn't necessarily look great, but at least much better than the GUI text labels, which are drawn on the framebuffer textures and apparently don't using any antialiasing at all.

Which brings me to my question: Is there a way to do decent curve text rendering on my custom framebuffer textures? Alternatively, what would be my best bet for quality text rendering? The AWT TextRenderer is a bit of a PITA as it interferes with my shaders and when I disable them, I lose my matrix functionality and would have to manually calculate the target coordinates. Or should I just take the same route I did with Android and write my own AWT-to-texture rendering code?

All suggestions welcome.
Reply | Threaded
Open this post in threaded view
|

Re: Text rendering quality

gouessej
Administrator
Hi

Don't use the legacy TextRenderer except if you're really aware of its dependencies. I'm a bit surprised by the text rendering in your screen capture :s
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Text rendering quality

Marian Schedenig
The screen cap is the result of the curve renderer. In what way does it surprise you?
Reply | Threaded
Open this post in threaded view
|

Re: Text rendering quality

Sven Gothel
Administrator
In reply to this post by Marian Schedenig
On 09/01/2013 04:56 PM, Marian Schedenig [via jogamp] wrote:

> I'm struggling with getting decent text rendering in my JOGL game. I
> originally wrote my GL code as Android native GL2ES code before porting it to
> JOGL for the desktop version. The Android code uses Android's own graphics
> library to render text strings to a texture and then display them via GL, but
> with JOGL I'm trying to rely on its own TextRenderer functionality instead of
> reinventing the wheel. Most of the remaining code is still pretty much the
> same it was on Android, so I'm using standard GL calls most of the time and
> JOGL specific classes only in a few instance, e.g. when setting up the GLWindow.
>
> Most of my text rendering occurs in my GUI classes, where each frame is
> rendered onto a framebuffer texture (created without any JOGL specific code)
> and then from there onto the main screen. I'm using my own primitive vertex
> and fragment shaders and the curve based TextRenderer seems to work well
> enough with those.
>
> This is my initialisation code:
>
> public TextRenderer getTextRenderer()
> {
>         if(textRenderer == null)
>         {
>                 ShaderState ss = new ShaderState();
>                 RenderState rs = RenderState.createRenderState(ss,
> SVertex.factory());
>                 int renderModes = 0;//GLRegion.VBAA_RENDERING_BIT;
>                 textRenderer = TextRenderer.create(rs, renderModes);
>                 textRenderer.init(gl);
>         }
>        
>         return textRenderer;
> }
>
> And here's how I render a text string, after setting up my shader's matrix
> correctly (which is why I always pass 0/0 as the coordinates):
>
> getTextRenderer().drawString3D(gl, glFont.getFont(), text.getText(), new
> float[]{0, 0}, (int) glFont.getSize(), new int[]{0});
>
> Problem is, the quality is rather lousy, as you can see in this image:
>
>
>
> The FPS display on the upper right is drawn directly on the screen and thus
> takes advantage of my GLWindow's sample buffer settings
> (caps.setNumSamples(4)). It doesn't necessarily look great, but at least much
> better than the GUI text labels, which are drawn on the framebuffer textures
> and apparently don't using any antialiasing at all.
Region.VBAA_RENDERING_BIT -> uses the FBO-AA method, which, tbh,
I would not recommend. VBO-AA results may vary on the AA settings.
Plus using MSAA on the final image may make things worse.

The above is especially true, if you render into an FBO already!
Use mode '0', i.e. direct curve rendering.

+++

You may also want to make your FBO use MSAA !

>
> Which brings me to my question: Is there a way to do decent curve text
> rendering on my custom framebuffer textures?
Of course.

Simple setup your FBO (use MSAA) and use the described direct rendering.
You may use our FBObject or GLOffscreenDrawable .. as you wish.

Further more: Your texture should be rendered w/ same aspect-ratio
and resolution as you have rendered the text.
Otherwise we are loosing the resolution independence :)
and 'gain' distortions.

BTW .. the whole idea of using Curved GPU based rendering
is to do it in the rendering loop -> resolution independence.
So caching the result in an FBO is sort of .. odd, but maybe
has it's merits due to your use-case.

> Alternatively, what would be my
> best bet for quality text rendering? The AWT TextRenderer is a bit of a PITA
> as it interferes with my shaders and when I disable them, I lose my matrix
> functionality and would have to manually calculate the target coordinates. Or
> should I just take the same route I did with Android and write my own
> AWT-to-texture rendering code?
>
> All suggestions welcome.

Please post a 'small' unit test / demo code under our BSD-3 license ..
Maybe add a bug report and we can take it from there ..

~Sven

>















signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Text rendering quality

Rami Santina
Administrator
In reply to this post by Marian Schedenig

You are rendering to texture. Thus it depends on two factors the fb size and the texture coords/usage.

From your screenshot,  I suppose that ur fb is tiny and not matching the final placement.

This textrenderer eval the curves in the frag shader so depending on the (number) of pixels your quality will enhance. So either use direct rendering..
Check the GUI sample or increase the FBO size etc...

On Sep 3, 2013 7:42 PM, "Marian Schedenig [via jogamp]" <[hidden email]> wrote:
The screen cap is the result of the curve renderer. In what way does it surprise you?


If you reply to this email, your message will be added to the discussion below:
http://forum.jogamp.org/Text-rendering-quality-tp4029946p4029972.html
To start a new topic under jogl, email [hidden email]
To unsubscribe from jogamp, click here.
NAML
Reply | Threaded
Open this post in threaded view
|

Re: Text rendering quality

Marian Schedenig
In reply to this post by Sven Gothel
Thanks for your reply (and sorry for my late commenting on it - I haven't had much time to work on my code recently).

I've been trying to switch my code to FBObject and activate multisampling. Using FBObject instead of direct GL calls seems to work nicely, but I can't figure out how to setup MSAA. I've never used MSAA before, and what bits and pieces I can gather from tutorials don't seem to port to FBObject.

When I set up a non-MSAA FBO, I can simply use attachTexture2D to generate a texture. But as soon as I switch to MSAA, this call fails, apparently because I'm not allowed to use attachTexture2D in this case. The JavaDoc doesn't give any indication as to how I *should* setup my FBO, and what's worse, I can't seem to find a single example on the net. Am I just missing some obvious search terms?

(The game is a simple 2D game using billboard quads, so all this fancy multisampling stuff is needed only to get acceptable text output quality).

@Rami: Obviously the rendered text shouldn't be stretched as a texture for final display. All my FBOs are sized and matrixed so I can do 1:1 pixel matching for the final screen quad.
Reply | Threaded
Open this post in threaded view
|

Re: Text rendering quality

Marian Schedenig
Much later, and after messing around with custom OpenGL code for creating MSAA FBOs I did get it half running, but in the end I decided to throw it all out and simply use AWT to draw strings to a texture. Works fine this way.
Reply | Threaded
Open this post in threaded view
|

Re: Text rendering quality

Sven Gothel
Administrator
On 08/19/2014 01:06 AM, Marian Schedenig [via jogamp] wrote:
> Much later, and after messing around with custom OpenGL code for creating MSAA
> FBOs I did get it half running, but in the end I decided to throw it all out
> and simply use AWT to draw strings to a texture. Works fine this way.

Of course, if it is 'enough' for your use case, fine.

MSAA will not lead to great results, since the fragment shader
does not operate on the supersampling 'position'.

Our view based (VBAA) shall be utilized to reach good results,
default is VBAA 'brute-force', 2nd best is flip-quad.

The following VBAA settings are recommended regarding display DPI:
  - ]299..   [ dpi: None (no AA required)
  - ]120..299] dpi: VBAA 2x
  - [ 90..120] dpi: VBAA 4x
  - [  0..119] dpi: VBAA 8x

http://jogamp.org/files/screenshots/graphui/20140324/
http://jogamp.org/files/screenshots/graphui/20140325/04-vbaa-allsamples/

BTW .. Rami and I will work on fixing remaining issues within the next month,
so the GPU based text renderer shall be stable by the end of this year.

~Sven


signature.asc (828 bytes) Download Attachment