Trivial Graphics Programming with GCC and Svgalib

From GLUG-BOM

You are here: Main Page >> Howtos >> Trivial Graphics Programming with GCC and Svgalib

This how-to is small introduction to graphics programming with C under most distributions (subject to the availability of graphic libraries). It is also a useful guide for students who are typically introduced to Turbo C++ 3.0 as a (compiler; IDE) software for computer graphics demos and would rather, like to explore graphics programming in their distro.

Turbo C++ 3.0 has a graphics.h file which consists of a large number of functions for demonstrating trivial geometric shape; creating huge code for gooey (GUI) programming using a combination of other libraries. This how-to starts with a link to using GCC under a distribution. (A beginner's guide to GCC is available here)

Contents

Graphics programming in DOS environment

I was excited when I understood, I could program in C and create geometric shapes just out of one single function. However, as it is always necessary to learn the alphabets of a language before trying to speak out a word, it was necessary to understand how that geometric figure would have been created painted on the screen. I remember the first graphics based program I wrote was drawing (painting) a line using the DDA algorithm.

Programming under DOS environment was my first experience with core computer graphics. I used the Turbo C++ 3.0 compiler (still used as default C compiler across undergraduate programs / postgraduate programs in Mumbai Univ. / College affltd.) to write programs for computer graphics. I managed to find out the capabilities of the software as an aid to computer graphics under DOS. (You could say, emulated DOS).

Often the programs written here are not portable. This means, if you write code using TC++3.0 and try to run it with a different compiler, it wont. Not directly. You'll have to re-write it or have similar libraries. This brings us to the next section of this how-to.

About Svgalib

Svgalib is a low-level graphics library that offers nearly the same capabilities that you would expect from such a library. It has several basic functions that'll help you write code that would produce nearly the same output as you would have expected from TC. There are two specific header files that one would use in C programs to use this library. They are vga.h and vgagl.h, the former allows use of basic graphic functions, the latter allowing slightly advanced functionality - all using functions.

Svgalib is is suitable for introductory Graphics programming in C. If you are further interested in game programming under your Linux distribution with a huge library, you might want to check out Allegro - Game programming library. It is available for Ubuntu (and its derivatives).

You might want to read Svgalib FAQ

Installing svgalib (Ubuntu)

There are two files that one has to install for using the svgalib. Under Ubuntu (or Debian based distros) - the following commands will fetch two packages from the internet. These two packages are necessary for getting started with graphics programming.

To list the packages, that would have to be installed, I enter the following command to find the exact name.

ubunturos@desktop:~$ sudo apt-cache search libsvga (return)
libsvga1 - console SVGA display libraries
libsvga1-dev - console SVGA display development libraries and headers
ubunturos@desktop:~$sudo apt-get install libsvga1(return)
ubunturos@desktop:~$sudo apt-get install libsvga1-dev (return)

(return) indicates "Enter / Return" button pressed and released.

For installing it under other distributions (such as Redhat / Slackware / Gentoo) please refer to their documentation.

Using svgalib

Svgalib is used by including vga.h and vgagl.h in C programs (typically). The library has a number of functions that is described under the man page of the library with each function having its own manpage. This means, at the "Console" you can type

man svgalib

and go through the man page. (Sure, I won't be telling you now to read the man page and not explain anything further. But this How-to is just an introduction, therefore an example follows)

vga_setcolor(int Color) 

is a function that can be used to set the current painting color. Color could have integer values mapping to colors such as black, red, green, blue etc. For example, red maps to 4. The colors and their mappings are available on a tutorial page here (which might probably kill the need of this how-to). To know details about each particular function (found in the man page of svgalib), you could type

man <functionname> 

where functionname is the name given in the manual page.

Sample programs

If you have a personal choice of using a text editor for writing programs (or code), fire it up now. Type in the following code that'll paint a line on the screen, using the co-ordinate system. This means, if you enter co-ordinates (lower values, typically) (say 0, 0, 100, 100) as initial and final coordiates, this program will display it according to the co-orindate system. (Postive X and Y values, fall in the first quadrant).

If you are unsure, which text editor you would like to use, open a terminal (konsole) and type kate, if you are on KDE. If you are on GNOME, type gedit. Alternately, if you would like to use something in the Console, you can type pico <filename.c> and start tying this program.

/*
 * Author: Roshan Baladhanvi
 * Email: d_rosh2001 at yahoo dot co dot in
 */

#include<stdio.h>
#include<stdlib.h>
#include<vga.h>

void draw_line(int, int, int, int);

//Draw the coordinate system for a 640x480 resolution. Could be generalized for other resolutions
void draw_axis(){
  vga_drawline(319,0,319,478);
  vga_drawline(0,239,638,239);
}

int main(void){
 int x1, y1, x2, y2; //Co-ordinates to draw a line
 
 vga_init(); //Initialize the Graphics array

 printf("Enter coordinates (x1, y1): ");
  scanf("%d %d", &x1, &y1);

 printf("Enter coordinates (x2, y2): ");
  scanf("%d %d", &x2, &y2);
 
 vga_setmode(4); //This mode sets the screen resolution of the graphics array to 640x480 pixels
 draw_axis(); //Call to function that displays the four quadrants (coordinate system)
 draw_line(x1, y1, x2, y2);

 vga_getch(); //Wait for a key from the user to quit the graphics array
 vga_setmode(0); //Set the screen mode back to text mode. 

 // Typically useful, when the user will run this program from the console and will be left back on to 
 // the text mode when the program exits. A good practise to do so.

 printf("\n");

 return 0;

}

void draw_line(int x1, int y1, int x2, int y2){	
  vga_drawline(x1+319, abs(y1-239), x2+319, abs(y2-239));	
}

To compile this program, open up a terminal and change to the directory where you have stored this file.

Type the following command to compile the program

gcc  -o firstg firstg.c -lvga (return)

To run the program, you may have to need to assign root permissions to the program. Check out

man chmod

to assign root permissions to the program.

Alternatively, if you are on Ubuntu (or its derivatives) you can use sudo command to execute the program

sudo ./firstg (return)

Below is another sample program that is a bit advanced than the one above.

To build a program that uses svgalib and/or vgagl, you need to link it to two libraries -- vgagl and vga, in that order. Hence, for the example below, your command would be:

gcc gradient.c -o gradient -lvgagl -lvga

Note that svgalib programs need to run as root. Read the Svgalib FAQ for more info.

To know more about various video modes that you can use, you can read the manpage for vga_setmode.


/*
 * gradient.c - Sample Program to draw a gradient using svgalib.
 */

#include <vga.h>
#include <vgagl.h>
#include <stdio.h>


int main() {
	int i=0,j=0,c=0;

	/* This should always be called before any svgalib or vgagl routines */
	vga_init();

	/* Set Video Mode to be used for drawing */
	if( vga_setmode(G1024x768x64K) == -1 ) {
		fprintf(stderr, "Video Mode not available\n");
		return 1;
	}

	/* 
	 * Set current graphics context to physical screen as defined by 
	 * vga_setmode() above 
	 */
	gl_setcontextvga(G1024x768x64K);

	/* Draw the gradient. Figure this one out yourself */
	for(i=0,j=0;i<255;j++,i++) {
		for(c=0;c<1024;c++)
                       /* Sets the color of the given pixel */
			gl_setpixelrgb(c,j,i,0,0);
	}
	for(i=0;i<255;j++,i++) {
		for(c=0;c<1024;c++)
			gl_setpixelrgb(c,j,255,i,i);
	}

	vga_getch();

	/* 
        * Reset the display mode of the physical screen back to text mode.
        * Again, don't forget this one.
        */
	vga_setmode(TEXT);

	return 0;
}