Simple Smooth Line Drawing with OpenGL

This article covers very basic smooth line drawing with OpenGL which can be easily implemented on different platforms.

Let’s start with basic requirements:

  • Lines should be straight, no curves (yet).
  • No dynamic weight .
  • No custom shaders (or no shaders for fixed pipeline).
  • Should support colouring.
  • Single texture image and just simple mesh structure (indices, vertex and texture coordinates)

Overall we’re targeting a method which is supported almost all 3D rendering platforms available right now, which can be easily implemented non OpenGL systems too.

The texture image is a transparent circle particle which will be atom of our lines.

particle

First step of the method is create a triangle pair to construct a square polygon and texture this polygon with the particle image:

line-05

Borders (triangle edge lines) are explicitly drawn to show what’s going under the hood.

Then we create many textured polygon instances along the line direction, from start to end:

line-01

Next step is to add more polygons and overlap them using a predefined step size, so circle particles start to look like a single line:

line-02

Starting to shape a line. Let’s increase the number of polygons while reducing the step size:

line-03

Now it looks like a straight smooth line. The step size for the above result is 1/8th of the texture image width. You can experiment and find the best step size for your needs. If you are not worried about a tight polygon budget, you can always select a value which is more than enough to be on the safe side.

Finally, removing borders reveals a smooth line:

line-04

One important step for this method is using a correct blending mode for overlapping polygons. One working for OpenGL ES is:

glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

Line weight (width) can be easily adjusted with changing polygon size, and colouring as easy as that just blending texture image or setting colour values for each vertices.

Below screenshots are the output from demo application which is written using the Processing language:

line-06

Same demo with random colours and transparency:

line-07

Of course this method can be improved to support different types of lines including curves and dynamic weighted ones.

Some further improvement ideas:

  • Triangle fans or strips could be used to reduce number of structural elements.
  • Curved lines (seems no additional steps required, just implement a curved line drawing algorithm ?)
  • Dynamic line weight (with resizing polygons gradually)
  • Since this method draws lines in 3D, you can actually do anything like a regular 3D mesh, rotating in 3D, scaling, morphing, perspective projection for a cool scrolling animation and  even an exploding effect.
  • Depth (z-coordinate) value should be used to handle overlapping line segments (especially with different colours).

You can download the Processing demo application from GitHub: https://github.com/akermen/smooth-line-drawing