[SDL] Alpha and per pixel alpha

Warren Schwader warrens at sierratel.com
Sat Nov 29 18:36:00 PST 2003

I had to write my own function to combine per pixel alpha and per surface alpha.
For my needs I also had a per program alpha that is a master alpha value so that I can reliably fade in or out the entire display (since gamma doesn't seem to be reliable enough for all configurations.

This code is for my TextSurface class that uses SDL_ttf, but I don't see any reason it wouldn't work on any other kinds of 32 bit surfaces.  This code will have to be modified for surfaces of other bit depths and is not very mature code yet.

In order for this to work, you must keep an original copy of the surface around so that the alpha can be recalculated from the original each time it is changed.  Then simply display the copy which has the alpha values set the way you want.

I'd really like to see functionality like this built into SDL.  Hope this helps.
--Warren Schwader

void TextSurface::SetAlpha(int alpha, int masterAlpha) 
 // calculate the alpha based on the master alpha for the entire game with this objects surface alpha setting
 // The netAlpha value will be used to determine each pixel's alpha setting
 int surfaceAlpha = (alpha * masterAlpha) / 255;
 // the pixels that make up the dats - not necessarily a simple 2d array
 Uint32* pixels = (Uint32*)_textSurface->pixels;

 // the surface width and height
 int width = _textSurface->w;
 int height = _textSurface->h;

 // the pitch of the surface.  Used to determine where the next vertical line in pixels starts
 int pitch = _textSurface->pitch;

 // this is the RGBA of a single pixel in the pixels array
 Uint32 pixel = 0;

 // the number of pixels for pitch instead of the numer of bytes
 Uint32 pitchPixels = pitch / 4;

 // this will refer to the alpha value of an individual pixel in the surface
 int pixelAlpha = 0;

 // for faster access
 SDL_PixelFormat* format = _textSurface->format;

 // this mask covers all the bits in the RGB section of the pixel, but not the Alpha portion
 Uint32 RGBMask = format->Rmask | format->Gmask | format->Bmask;
 // some other shortcuts to make the inner loop as fast as possible
 Uint32 alphaShift = format->Ashift;
 Uint32 alphaMask = format->Amask;

 int ndx = 0;
 for (int h = 0; h < height; h++)
  // for each vertical line, calculate the starting index.  Each pixel in that line will then be contiguous
  ndx = (h * pitchPixels);
  for (int w = 0; w < width; w++)
   pixel = pixels[ndx];
   pixelAlpha = (pixel & alphaMask) >> alphaShift;

   if (pixelAlpha > 0)
    // calculate the new pixel alpha value and shift it into the location of the alpha bits
    pixelAlpha = ((pixelAlpha * surfaceAlpha) / 255) << alphaShift;

    // first AND out the alpha portion so that they are 0 and then OR in the new alpha value
    pixels[ndx] = (pixel & RGBMask) | pixelAlpha;  
  ----- Original Message ----- 
  From: Dmitry Borisov 
  To: sdl at libsdl.org 
  Sent: Thursday, November 06, 2003 10:40 PM
  Subject: [SDL] Alpha and per pixel alpha

  Is there any way to have per surface alpha combined with per pixel alpha together ?
  In a sense it means that I want to use TTF with antialiasing and then blit it to the surface with additional transparency.
  Can I do that ?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20031129/e7a16854/attachment-0008.htm>

More information about the SDL mailing list