VGA Graphics Programming

Here you can learn some basic graphics programming techniques. Only basic programming knowledge is assumed. We recommend users to go through the tutorial in sequence and check all the examples.

Setting Video Mode

To begin with you need to set the mode on the PC's video card. This function will achieve this:

void set_video_mode(int mode)
{
	union REGS regs;
	regs.x.ax = mode;
	int86(0x10, ®s, ®s); //DOS interrupt to set video mode
}

We are using the popular Mode 13 because it allows 200X320 resolution with 256 colours, so call this function with 13hex like this:

set_video_mode(0x013);

Finally, when the program is complete it is sensible to return to the normal text video mode (remember this is a DOS program)

set_video_mode(0x03);
  Download a working example
If you don't have DJGPP, download it here

The colour palette

As you will want to see the pixels you draw you must set the palette up (otherwise you will only draw black pixels). Here is the code to put a colour into one of the palettes 256 indexes:

void set_palette_register(unsigned char index, rgb_color* color)
{
	outportb(0x3c6, 0xff);
	outportb(0x3c8, index);
	outportb(0x3c9, color->red);
	outportb(0x3c9, color->green);
	outportb(0x3c9, color->blue);
}

The data type rgb_color is one you will need to add a definition for:

typedef struct rgb_color_type
{
	unsigned char red;
	unsigned char green;
	unsigned char blue;
} rgb_color;

Each component in the structure (red,green,blue) can have a value from 0 to 63. An example is included in the next section.

Displaying Pixels

Think of your screen as a pictorial view of video memory. To display pixels you simply need to write a byte to video memory. The value of the byte is an index for the 256 colour palette. The screen is set up like this:

Here is the put_pixel code:

void put_pixel(short int x, short int y, char color)
{
	video_buffer[(y << 8) + (y << 6) + x] = color;
}

This should be all you need to draw a coloured pixel on the screen. Whoohoo!

  Download a working example

Buffering the Display

It is worth writing all your pixels to a buffer first and then copying the whole lot to video memory in one go. Otherwise the screen will flicker with many things being drawn at different times.

Define double_buffer as an array the same size as video memory:

char *double_buffer;
double_buffer=(char *)malloc(64000);//(200*320)

The malloc function used will dynamically (at run time) allocate 64000 bytes of memory to the buffer. Because the memory is allocated during runtime, it must also be freed at the program end:

free(double_buffer);

Now change the pixel function...

void put_pixel(short int x, short int y, char color)
{
	double_buffer[(y << 8) + (y << 6) + x] = color;
}

...so that it writes to the buffer. You can then 'draw' the whole lot in one go like this:

memcpy((char *)video_buffer,(char *)double_buffer,64000);
  Download a working example

Loading an Entire Palette

Rather than painstakingly setting up a colour palette, just load a complete one from a bitmap file:

void loadPal256(char* fileName)
{
	FILE* bmpFile = fopen(fileName, "rb");
	short int i;
	rgb_color col;
	fseek(bmpFile, 54, SEEK_SET);
	for (i = 0; i < 256; i++)
	{
		col.blue = fgetc(bmpFile) / 4;
		col.green = fgetc(bmpFile) / 4;
		col.red = fgetc(bmpFile) / 4;
		fgetc(bmpFile);           					//reserved i.e. not used
		set_palette_register(i, &col);
	}
	fclose(bmpFile);
}

Call this function with the name of a bitmap file. The bitmap must be 256 colour format.

  Download a working example