Skip to content
cbaakman edited this page Oct 5, 2018 · 8 revisions

Text GL can be used for displaying text in the 3D library OpenGL, but it does more than that. For example: it can tell you on which character the mouse cursor is currently pointing. This enables you to have selectable text.

OpenGL

Useful OpenGL tutorials can be found here: http://nehe.gamedev.net/

Font Data

Your font data has to be an SVG file, according to the standards at https://www.w3.org/TR/SVG11/fonts.html. Used variables are:

  • bbox: the bounding box for the glyphs. Text GL assumes no glyph is rendered outside this box.
  • glyph d: the path, or control points of the glyphs, this describes how to draw the glyph in 2D
  • horiz-adv-x: the character horizontal coordinate incrementation, either per glyph or for the whole font
  • horiz-origin-x: the character horizontal bearing, either per glyph or for the whole font
  • horiz-origin-y: the character vertical bearing, either per glyph or for the whole font
  • hkern k, g1/u1, g2/u2: the horizontal kerning combinations, can be single character combo's or group combo's (kerning by class)

Text GL currently assumes that glyphs are positioned in horizontal lines, from left to right. So Arabic or Chinese texts are not supported.

To generate SVG font files easily, use fontforge: https://fontforge.github.io/en-US/

Parsing Font Data

Parsing only requires a single function, but that function needs a C++ istream object as input:

#include <iostream>
#include <fstream>
#include <text-gl/font.h>

using namespace TextGL;

FontData fontData;

std::ifstream is;
is.open("my-font.svg");
if (!is.good())
  std::cerr << "Error opening file." << std::endl;

ParseSVGFontData(is, fontData);

Generating an Image Font

Font data alone cannot be rendered in OpenGL. The next step is to rasterize the glyphs and create an image font. This also requires you to set the font style:

#include <text-gl/image.h>

FontStyle style;
style.size = 32.0;
style.strokeWidth = 2.0;
style.fillColor = {1.0, 1.0, 1.0, 1.0};
style.strokeColor = {0.0, 0.0, 0.0, 1.0};
style.lineJoin = LINEJOIN_MITER;
style.lineCap = LINECAP_SQUARE;

ImageFont *pImageFont = MakeImageFont(fontData, style);

Once an image font is created, it's glyph images and style can no longer be changed.

Creating a GL Texture Font

Glyph images need to be converted to textures, in order to render text in OpenGL. To do so however, A valid OpenGl context is needed. How this is created varies per platform. Here's an example.

#include <text-gl/tex.h>

GLContext context = CreateGLContext(canvas);  // This is platform specific!

GLTextureFont *pTextureFont = MakeGLTextureFont(pImageFont);

Iterating over Text

Text GL doesn't completely implement text rendering. It simply provides the user with the tools to do so himself. For example to render a line of text:

#include <text-gl/text.h>

const int8_t text[] = "\'Ж\' is a cyrillic character."

class TextRenderer: public GLTextLeftToRightIterator
{
  void OnGlyph(const UTF8Char c, const GlyphQuad &quad, const TextSelectionDetails &details)
  {
    glBindTexture(quad.texture);

    size_t i;
    for (i = 0; i < 4; i++)
    {
      glTexCoord(quad.vertices[i].tx, quad.vertices[i].ty);
      glVertex2f(quad.vertices[i].x, quad.vertices[i].ty);
    }
  }
};

TextRenderer renderer;

TextParams params;
params.startX = 0.0f;
params.startY = 0.0f;
params.maxWidth = 600.0f;
params.lineSpacing = 40.0f;
params.align = TEXTALIGN_LEFT;

renderer.IterateText(pTextureFont, text, params);

Text GL allows you to override a text iterator class. 'IterateText' calls the function 'OnGlyph' for every glyph that needs to be shown. (one way or another) 'OnGlyph' takes three arguments:

  • The actual character.
  • The glyph quad that needs to be rendered, containing four vertex points and a texture.
  • Details about the text position: start character number (0, 1, 2, ..); end character number position; baseline y value; start and end x value

Of coarse the iterator class can be used for other things than rendering glyphs alone. You can do anything on a per-character of per-glyph basis.

Deleting

Once you are done with your fonts, you must delete them. Be sure to delete the GL texture font before you delete the GL context:

DestroyGLTextureFont(pTextureFont);

DestroyGLContext(context);  // This is platform specific!

DestroyImageFont(pImageFont);
Clone this wiki locally