In an earlier post we had discussed the framebuffer object of the C library for performing graphics on the OLED screen SSD1306 using a Raspberry Pi. We also discussed how to draw text using FreeType2.
In this post we show you how to draw straight lines on the OLED screen using our
ssd1306_framebuffer_draw_line()
function.
The code in this post is as of commit 597002e7e6792ff236f760c11d67ff6a6d719ab9
from Github.
There may be several algorithms to draw lines on a screen, but for our case we use the Bresenham’s line drawing algorithm as described in the great Michael Abrash’s Graphics Programming Black Book. The book explains in great detail how the algorithm works and how to draw to a VGA or EVGA screen using the x86 processor. We have appropriately adjusted the algorithm to work correctly for our OLED screen and also be more generic to work on both ARM and x86 chips, but most of the algorithm does not change from what is in the book’s chapter.
Our function here is ssd1306_framebuffer_draw_line()
which takes 6 arguments:
the framebuffer pointer, the (x0, y0) starting point
coordinates, the (x1, y1) ending point coordinates and
the pixel color for whether to draw a clear (black) or filled (blue)
pixel for the line.
In the examples/draw_line.c
we draw three different lines - a horizontal line
at 0°, a vertical line at 90° and a diagonal line between two random points.
If we want to draw a horizontal line from (0,0)
to (64,0)
with a filled
pixel, our function call will look like:
#include <ssd1306_graphics.h>
/* ... some initialization code ... */
/* create the framebuffer for a OLED screen 128x32 */
ssd1306_framebuffer_t *fbp = ssd1306_framebuffer_create(128, 32, NULL);
// draw the line
ssd1306_framebuffer_draw_line(fbp, 0, 0, 64, 0, true);
// dump the framebuffer memory with no-spaces
ssd1306_framebuffer_bitdump_nospace(fbp);
The framebuffer dump looks like:
0000 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||................................................................
0001 ................................................................................................................................
0002 ................................................................................................................................
0003 ................................................................................................................................
0004 ................................................................................................................................
0005 ................................................................................................................................
0006 ................................................................................................................................
0007 ................................................................................................................................
0008 ................................................................................................................................
0009 ................................................................................................................................
000A ................................................................................................................................
000B ................................................................................................................................
000C ................................................................................................................................
000D ................................................................................................................................
000E ................................................................................................................................
000F ................................................................................................................................
0010 ................................................................................................................................
0011 ................................................................................................................................
0012 ................................................................................................................................
0013 ................................................................................................................................
0014 ................................................................................................................................
0015 ................................................................................................................................
0016 ................................................................................................................................
0017 ................................................................................................................................
0018 ................................................................................................................................
0019 ................................................................................................................................
001A ................................................................................................................................
001B ................................................................................................................................
001C ................................................................................................................................
001D ................................................................................................................................
001E ................................................................................................................................
001F ................................................................................................................................
If we want to draw a vertical line from (64,0)
to (64,32)
with a filled
pixel, our function call will look like:
#include <ssd1306_graphics.h>
/* ... some initialization code ... */
/* create the framebuffer for a OLED screen 128x32 */
ssd1306_framebuffer_t *fbp = ssd1306_framebuffer_create(128, 32, NULL);
// draw the line
ssd1306_framebuffer_draw_line(fbp, 64, 0, 64, 32, true);
// dump the framebuffer memory with no-spaces
ssd1306_framebuffer_bitdump_nospace(fbp);
The framebuffer dump looks like:
0000 ................................................................|...............................................................
0001 ................................................................|...............................................................
0002 ................................................................|...............................................................
0003 ................................................................|...............................................................
0004 ................................................................|...............................................................
0005 ................................................................|...............................................................
0006 ................................................................|...............................................................
0007 ................................................................|...............................................................
0008 ................................................................|...............................................................
0009 ................................................................|...............................................................
000A ................................................................|...............................................................
000B ................................................................|...............................................................
000C ................................................................|...............................................................
000D ................................................................|...............................................................
000E ................................................................|...............................................................
000F ................................................................|...............................................................
0010 ................................................................|...............................................................
0011 ................................................................|...............................................................
0012 ................................................................|...............................................................
0013 ................................................................|...............................................................
0014 ................................................................|...............................................................
0015 ................................................................|...............................................................
0016 ................................................................|...............................................................
0017 ................................................................|...............................................................
0018 ................................................................|...............................................................
0019 ................................................................|...............................................................
001A ................................................................|...............................................................
001B ................................................................|...............................................................
001C ................................................................|...............................................................
001D ................................................................|...............................................................
001E ................................................................|...............................................................
001F ................................................................|...............................................................
A line that is not at 0° or 90° or a 1:1 diagonal will have to be approximately drawn using Bresenham’s line drawing algorithm as noted above. As part of the algorithm sometimes to make the line look neat, we have to color two pixels in each row as you can see in the framebuffer dump below to get the perfect look of the line.
#include <ssd1306_graphics.h>
/* ... some initialization code ... */
/* create the framebuffer for a OLED screen 128x32 */
ssd1306_framebuffer_t *fbp = ssd1306_framebuffer_create(128, 32, NULL);
// draw the line
ssd1306_framebuffer_draw_line(fbp, 0, 0, 64, 32, true);
// dump the framebuffer memory with no-spaces
ssd1306_framebuffer_bitdump_nospace(fbp);
0000 |...............................................................................................................................
0001 .||.............................................................................................................................
0002 ...||...........................................................................................................................
0003 .....||.........................................................................................................................
0004 .......||.......................................................................................................................
0005 .........||.....................................................................................................................
0006 ...........||...................................................................................................................
0007 .............||.................................................................................................................
0008 ...............||...............................................................................................................
0009 .................||.............................................................................................................
000A ...................||...........................................................................................................
000B .....................||.........................................................................................................
000C .......................||.......................................................................................................
000D .........................||.....................................................................................................
000E ...........................||...................................................................................................
000F .............................||.................................................................................................
0010 ...............................||...............................................................................................
0011 .................................||.............................................................................................
0012 ...................................||...........................................................................................
0013 .....................................||.........................................................................................
0014 .......................................||.......................................................................................
0015 .........................................||.....................................................................................
0016 ...........................................||...................................................................................
0017 .............................................||.................................................................................
0018 ...............................................||...............................................................................
0019 .................................................||.............................................................................
001A ...................................................||...........................................................................
001B .....................................................||.........................................................................
001C .......................................................||.......................................................................
001D .........................................................||.....................................................................
001E ...........................................................||...................................................................
001F .............................................................||.................................................................
In the example file examples/i2c_128x32_graphics.c
we have added a call to the
line drawing function and below are some images from drawing the line on the
screen.
Figure 1. Drawing a diagonal line
Figure 2. Drawing vertical and diagonal lines
Figure 3. Drawing horizontal, vertical and diagonal lines