How to set a pixel in a SDL_surface?

c, c++, graphics, sdl

Solution

- Since each pixel has size 4 (the surface is using `Uint32`-valued pixels), but the computation is being made in `Uint8`. The `4` is ugly, see below.

- To make the address calculation be in bytes.

- Since the pixel to be written really is 32-bit, the pointer must be 32-bit to make it a single write.

The calculation has to be in bytes since the surface's `pitch` field is in bytes.

Here's a (less aggressive than my initial attempt) re-write:

void set_pixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
  Uint32 * const target_pixel = (Uint32 *) ((Uint8 *) surface->pixels
                                             + y * surface->pitch
                                             + x * surface->format->BytesPerPixel);
  *target_pixel = pixel;
}

Note how we use `surface->format->BytesPerPixel` to factor out the `4`. Magic constants are not a good idea. Also note that the above assumes that the surface really is using 32-bit pixels.

Problem

I need to use the following function from this page. The SDL_Surface structure is defined as ``` typedef struct SDL_Surface { Uint32 flags; /* Read-only */ SDL_PixelFormat *format; /* Read-only */ int w, h; /* Read-only */ Uint16 pitch; /* Read-only */ void *pixels; /* Read-write */ SDL_Rect clip_rect; /* Read-only */ int refcount; /* Read-mostly */ } SDL_Surface; ``` The function is: ``` void set_pixel(SDL_Surface *surface, int x, int y, Uint32 pixel) { Uint8 *target_pixel = (Uint8 *)surface->pixels + y * surface->pitch + x * 4; *(Uint32 *)target_pixel = pixel; } ``` Here I have few doubts, may be due to the lack of a real picture. - Why do we need to multiply `surface->pitch` by `y`, and `x` by `4`? - What is the necessity of declaring `target_pixel` as an `8-bit integer pointer` first, then casting it into a `32-bit integer pointer` later? - How does `target_pixel` retain the `pixel` value after the `set_pixel` function return?

Original source