3

I created the ftmesh library to draw fonts on my OpenGL ES 3 screen. The code works, but the edges of the characters is raggedy. I'm using an NVidia Jetson AGX Xavier with OpenGL ES 3 and the glShadeModel(GL_SMOOTH) doesn't have any effect (and glEnable(GL_POLYGON_SMOOTH) says Invalid Enum—since it's not allowed in ES 2 or 3).

Here is an example of a screenshot showing the ugly edges:

enter image description here

Is the only option to add an offset edge all around and make the outside part 100% transparent?

Or is there a way to do it with a shader? It would be fantastic to get a link to an example.

My current shader just transmits the vertices as is:

varying vec4 polygon_color;

attribute vec2 in_position;
attribute vec4 in_color;

void main()
{
    polygon_color = in_color;
    gl_Position = vec4(in_position.xy, 0, 1);
}

And here is the fragment shader:

varying vec4 polygon_color;

void main()
{
    gl_FragColor = polygon_color;
}

I set all the in_color vertices to (1.0f, 1.0f, 1.0f, 0.75f) before the glDrawArrays() call.

Sample Buffers (Solution)

As suggested by Rabbid76 in a comment, I tried adding multisampling. It has an effect, it created a form of grid, though... much more transparent than expected (see picture below).

  1. In my g_egl_visual_attributes I added EGL_SAMPLE_BUFFERS like so:

     constexpr EGLint const g_egl_visual_attributes[] =
     {
         EGL_RED_SIZE, 8,
         EGL_GREEN_SIZE, 8,
         EGL_BLUE_SIZE, 8,
         EGL_ALPHA_SIZE, 8,
         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
         EGL_SAMPLE_BUFFERS, 1,   // <-- added this option
         EGL_SAMPLES, 8,          //     and this one
         EGL_NONE,
     };
    

    Note: with my configuration, EGL_SAMPLES of 16 doesn't work (no such buffer available).

  2. Then I enabled the sample alpha coverage

     glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
     glEnable(GL_SAMPLE_COVERAGE);
    

    But that had the side effect shown below...

    enter image description here

  3. So I tried without the glEnable() calls and now that works as expected]!

    If you look closely, in this last image we can see the anti-aliasing on the edges:

    enter image description here

    So MSAA resolved the issue.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
  • 1
    If I understand you correctly, the letter is drawn by a polygon. What about [Multisampling](https://www.khronos.org/opengl/wiki/Multisampling)? – Rabbid76 May 09 '21 at 20:16
  • I actually use the `GL_TRIANGLES` because ES does not have the notion of polygons. This is why I had to use a library that generates a mesh. It supports `GL_TRIANGLE_FAN` and `GL_TRIANGLE_STRIP`, but at this time I avoid those. I would think, anyway, that this would give a similar result. – Alexis Wilke May 09 '21 at 20:20
  • `GL_TRIANGLES` is polygon primitiv. There are points, lines and polygons (like triangles - see [Primitive](https://www.khronos.org/opengl/wiki/Primitive)). So you re drawing triangles. Read about [Multisampling](https://www.khronos.org/opengl/wiki/Multisampling). – Rabbid76 May 09 '21 at 20:24
  • @Rabbid76 Okay! I was able to make it work simply by adding `EGL_SAMPLE_BUFFERS, 1,` to the visual attributes! Thank you for the pointers. – Alexis Wilke May 09 '21 at 22:07
  • Is using pre-rendered textures an option? – HolyBlackCat May 09 '21 at 22:20
  • @HolyBlackCat I already have such, but it's actually very slow to generate many strings and then render that texture. So that's why I create the ftmesh project to get the triangles. And that uses just a few % of the CPU. – Alexis Wilke May 09 '21 at 22:28
  • The state of the art is to use a texture atlas that stores every glyph, and render text using those. And instead of just a bitmap image of each glyph, a signed distance field (SDF) can be used to even make it look good when zooming in and out. See: https://github.com/Chlumsky/msdfgen – G. Sliepen May 09 '21 at 22:50

1 Answers1

1

A much nicer anti-aliasing is provided by the library FreeTypeGL, but it renders the characters in a completely different manner, by means of a distance map, and as a side effect it doesn't make perfect corners:

https://github.com/rougier/freetype-gl

  • That looks like a fine piece of code, but I'm wondering about speed now... my solution just added a tad bit of EGL code, the library you reference would be huge in comparison. – Alexis Wilke Jan 01 '22 at 20:35