How can we draw Fonts in OpenGL
Tags: programming, opengl, 3drendering, 3dgraphics
Published: 2024-02-11 08:49:59

We can draw all kinds of 3D Models in OpenGL. But oftentimes we also need to draw Fonts in OpenGL. How can we make that?

Luckily there are a few open-source fonts rendering libraries out there. I'll guide you to make use of one of them: `FTGL`.

I. Libraries we'll need to use.

- OpenGL
- FTGL
- freeglut
- freetype

II. Compile the libraries in `Visual Studio 2022 / VC++`.

- freeglut

I downloaded `freeglut v3.4.0` from Sourceforge. And use CMake to build VC++ project management files.
CMake has a very easy to use GUI on Windows platforms.

With the generated `freeglut.sln` we can open the project. Select building options of `x64 & release`.
As we don't need other external libraries, we can build it directly.

Then we'll have a `freeglut.lib` or `freeglut_static.lib` for later use.

- freetype

I downloaded `freetype v2.13.2` from freetype.org. 

I'll recommend you to get the sources packages from their official websites if they have. You'll encounter fewer building errors in stead of using the newest code from their GitHub repositories.

After all, tuning rendering effects are much more interesting than solving building blockers.

We can open the default `freetype.sln` provided by this source package in VC++ to build it. Before start building, please select `x64 & release` options first. After that, we'll get the binary `freetype.lib`.

- FTGL

We can use default `ftgl.sln` in source package to build. Please select `x64 & release` first.
And we'll need to configure `include paths` & `library paths` to the project. We'll also need to add `freeglut.lib` & `freetype.lib` to the linker settings.
In the end, we'll get `ftgl.lib`.

III. Write a FTGL demo. Sample code:

```cpp
// Demo code
void Demo_code(void)
{
	// Resolutions of the picture
	const GLfloat width = 800;
	const GLfloat height = 600;

	glShadeModel(GL_SMOOTH);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClearDepth(1.0f);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	// Load the Font
	// Use any TTF font name you like here
	font = (FTGLfont*)new FTGLPolygonFont("./Mona-Regular-2.ttf");
	if (((FTGLPolygonFont*)font)->Error())
	{
		fprintf(stderr, "Failed to load font\n");
		return;
	}

	// Clear all pixels
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	// Set perspective view
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);

	glPushMatrix();
	// Place camera
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	// Adjust the position of the text
	glTranslatef(-0.5f, 0.0f, -5.0f);
	// Rotate the text to be vertically
	glRotatef(55.0f, 0.0f, 1.0f, 0.0f);
	glScalef(0.35f, 0.35f, 0.35f);

	if (font)
	{
		// Render Fonts
		((FTGLPolygonFont*)font)->FaceSize(0);
		glTranslatef(-6.0f, 0.0f, 0.0f);
		((FTGLPolygonFont*)font)->Render("You know Bill?");

		glColor4d(0.0, 0.0f, 1.0f, 0.8f);
		glTranslatef(0.0f, -1.0f, 0.0f);
		((FTGLPolygonFont*)font)->Render("You know Bill?");
	}

	glPopMatrix();
	// Render
	glutSwapBuffers();
}
```

IV. Compile the sample code into executable binary.

We need to confifgure the VC++ project with `include paths`, `library paths` and `libraries` prior building:
- ftgl.lib
- freeglut.lib
- freetype.lib

V. Rendering results.

The library can render fonts into multiple styles.

- Polygon mode

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/627v2n0v747kddy3yo8k.jpg)

- Outline mode


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kf9oh90r7rgcq3wzsh73.jpg)

- Extrude mode


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lh354v89pi4nzv9o8mnb.jpg)

And more!

Don't forget to copy the TTF font file and any DLL files you're leveraging to executable folder to try the Demo.

Hope you enjoy the FTGL 3D Fonts rendering library for OpenGL. It's a wonderful library! 😊