Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: July 6, 2024
BGI (Borland Graphics Interface) provides an easy way for us to get our hands wet in the world of graphics programming. In this article, we’ll build and install an alternative implementation of BGI for Linux known as libgraph.
In addition, we’ll also discuss OpenGL as an alternative to libgraph.
BGI was a C/C++ graphics library for the Borland compilers. It was written for the DOS operating system in the 1980s. However, it was maintained until the Borland C++ 5.02 compiler.
The BGI library is accessible through graphics.h. In addition, it’s very straightforward to use because it has no support for 3D graphics and event handling.
BGI was solely implemented for DOS. However, there is an open-source library called libgraph that implements BGI for Linux. It’s built on top of SDL (Simple DirectMedia Layer), which is a low-level multimedia library that provides an abstraction layer for hardware components.
libgraph isn’t as powerful as SDL itself. However, it’s very easy to use for learning purposes.
In this section, we’ll install libgraph alongside its dependencies. Unfortunately, on modern Linux systems, most libgraph dependencies are not widely available on the official package repositories.
Therefore, it’s going to be a bit of work to collect the required artifacts.
On Ubuntu 17.10 and previous versions, we can simply install the dependencies from the package repositories:
$ sudo apt install -y libsdl-image1.2 libsdl-image1.2-dev guile-1.8 \
guile-1.8-dev libsdl1.2debian libart-2.0-dev libaudiofile-dev \
libesd0-dev libdirectfb-dev libdirectfb-extra libfreetype6-dev \
libxext-dev x11proto-xext-dev libfreetype6 libaa1 libaa1-dev \
libslang2-dev libasound2 libasound2-dev build-essential
For Ubuntu 18.04+, we’ll add the Xenial Xerus (Ubuntu 16.04) repositories to the sources.list file:
# Binaries
$ echo "deb http://us.archive.ubuntu.com/ubuntu/ xenial main universe" | sudo tee -a /etc/apt/sources.list
# Sources
$ echo "deb-src http://us.archive.ubuntu.com/ubuntu/ xenial main universe" | sudo tee -a /etc/apt/sources.list
Now, let’s import the missing public keys to verify the integrity of the packages:
$ gpg --keyserver keyserver.ubuntu.com --recv-keys 40976EAF437D05B5 3B4FE6ACC0B21F32
Then, let’s update the package cache:
$ sudo apt update
Finally, let’s install the dependencies:
$ sudo apt install -y libsdl-image1.2 libsdl-image1.2-dev guile-2.0 \
guile-2.0-dev libsdl1.2debian libart-2.0-dev libaudiofile-dev \
libesd0-dev libdirectfb-dev libdirectfb-extra libfreetype6-dev \
libxext-dev x11proto-xext-dev libfreetype6 libaa1 libaa1-dev \
libslang2-dev libasound2 libasound2-dev
Once the dependencies are installed, we can now build libgraph.
First, we’ll need to download libgraph:
$ curl -LO "http://download.savannah.gnu.org/releases/libgraph/libgraph-1.0.2.tar.gz"
Next, we extract the contents of the archive:
$ tar -xvf libgraph-1.0.2.tar.gz
Afterward, we cd into it and run configure:
$ cd libgraph-1.0.2/ && ./configure
Once all the checks are passed, the script creates a Makefile. Then, we simply build the sources:
$ make
Now, let’s install the libraries:
$ sudo make install
Finally, we copy the required libraries to /usr/lib as well:
$ sudo cp /usr/local/lib/libgraph.* /usr/lib
We copied the libraries to /usr/lib because it’s the system-wide shared libraries directory. Therefore, they are available to all the programs on the system.
In contrast, if we left the libraries in /usr/local/lib, we’ll need to provide additional configuration to the linker during the building process of our graphics program.
Now, we’re ready to include the <graphics.h> header file in our C/C++ source code. As an example, we’ll write a simple program to test this out:
#include <graphics.h>
int main(int argc, char** argv) {
int gd = DETECT, gm;
initgraph(&gd, &gm, NULL);
circle(180, 280, 80);
line(100, 150, 160*3, 150);
delay(10000);
closegraph();
return 0;
}
Let’s dig into this:
Usually, the program exits when the closegraph function is called.
At this point, libgraph is very old. No matter how easy it is, over time, it will become more difficult to build it on Linux. Therefore, we can opt for other alternatives like OpenGL.
OpenGL is a graphics API that enables us to develop complex 2D and 3D applications. In contrast to libgraph, it has a steep learning curve. However, there are many learning resources available over the web.
A simpler way to get started with OpenGL is to use FreeGLUT. FreeGLUT is a cross-platform window management library with OpenGL context.
We install it from the official package repositories:
$ sudo apt install -y freeglut3 freeglut3-dev
Once installed, let’s write a simple program that draws a rectangle:
#include <GL/freeglut.h>
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
glVertex2f(-0.5f, -0.5f);
glVertex2f(0.5f, -0.5f);
glVertex2f(0.5f, 0.5f);
glVertex2f(-0.5f, 0.5f);
glEnd();
glFlush();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutCreateWindow("Baeldung on Linux Graphics");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Now, let’s build it:
$ gcc main.c -o demo -lglut -lGL
Finally, let’s test it out:
$ ./demo
The program creates a window with the given title and draws a rectangle with the given vertices:
In addition, the code also calls glutMainLoop, which waits for events and updates. Therefore, when we press the close button, it closes the window.
In this tutorial, we discussed how to build and install libgraph, which is an alternative BGI library for Linux. As an alternative to libgraph, we also looked at the OpenGL API through FreeGLUT.