[SDL] Alpha and per pixel alpha

Warren Schwader warrens at sierratel.com
Sat Nov 29 20:39:00 PST 2003


Actually the code I listed had a bug so I am posting the correct version:

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* origPixels = (Uint32*)_textSurfaceOrig->pixels;
 Uint32* destPixels = (Uint32*)_textSurface->pixels;

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

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

 // the pitch of the surface.  Used to determine where the next vertical line in pixels starts
 int pitch = _textSurfaceOrig->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 / format->BytesPerPixel;

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

 // 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;
 
 // other time savers because these are used in the inner loop
 Uint32 alphaShift = format->Ashift;
 Uint32 alphaMask = format->Amask;

 // NOTE:  Since we are only modifying the alpha bytes we could simply read only that byte and then add 4 to get
 // to the next alpha byte.  That approach depends on the endianess of the alpha byte and also the 32 bit pixel depth
 // so if those things change then this code will need changing too.  but we already rely on 32 bpp
 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 = origPixels[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
    destPixels[ndx] = (pixel & RGBMask) | pixelAlpha;  
   }
   ndx++;
  }
 }
}

  ----- Original Message ----- 
  From: Warren Schwader 
  To: sdl at libsdl.org 
  Sent: Saturday, November 29, 2003 6:35 PM
  Subject: Re: [SDL] Alpha and per pixel alpha


  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

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


More information about the SDL mailing list