Drawing Pixels in SDL

We've been analysing our SDL example program to see how it works. In this lesson, we'll look at how to use SDL to draw pixels on the screen.

The function that draws-na a pixel on the screen in our example program, is called setpixel. It takes six arguments: an SDL surface, the x and y coordinates of the pixel and the red, green and blue components of the colour that we'd like our pixel to be.

Each of the colour components is 8 bits. In order to specify that we want variables of exactly 8 bits, we use the new Uint8 type, which stands for an unsigned integer of precisely 8 bits.

Now you might notice that with three colour components of 8 bits, we only get 24 bits of colour information in total, yet we have specified a colour depth of 32 bits for our drawing surface.

In order to get the right number of bits, we need to convert our colour information to a format which matches that of our drawing surface. To do this we use the following lines of code:

Uint32 colour;  
 
colour = SDL_MapRGB( screen->format, r, g, b );

This converts our 24 bits of colour information into a single 32 bit number, which is ready to put down at the appropriate place in screen memory.

Inside the SDL_Surface structure is a field called pixels, which is essentially the screen memory corresponding to the drawing surface we requested from SDL. Each 32 bits of data in this array corresponds to a pixel on the screen, starting at the top left corner of our drawing surface (in our case the the whole screen) running across each row in order and finishing at the bottom right hand corner.

In order to put our pixel on the screen, we just need to store the 32 bit colour variable at the appropriate array location in the array of pixels. Since there are 640 pixels, each taking four bytes, across each row of the screen, we need to multiply the y-coordinate of our pixel by 640*4. Then we add to it the x-coordinate multiplied by 4.

Because all these multiplications are time consuming however, we will assume these multiplications have already been done, outside our setpixel function. In other words, we'll pass in the y-coordinate multiplied by 640*4 and the x-coord multiplied by 4 when we draw a pixel.

The lines of code for drawing the pixel at the appropriate location are now:

Uint32 *pixmem32;
  
pixmem32 = (Uint32*) screen->pixels  + y + x;
*pixmem32 = colour;

pixmem32 is a pointer to the screen location where our pixel should go. The star in front of it, on the final line here, is called dereferencing the pointer. It says that we want to put the value of the variable colour not into the pointer itself, but into the location pointed to by the pointer, i.e. in screen memory.