Fading of RGBA surfaces

Hi folks!

I have a png with an alpha layer and it displays correct with alpha channel
on the screen. But how can I set a specific transparency value thru
SDL_SetAlpha() (it ignores it simply). When I convert the surface to a RGB
(SDL_DisplayFormat() and not SDL_DisplayFromatAlpha()) the alpha channel is
not there and I can set the transparency value.

As declared in the subject I need this for some fading surfaces. I hope you
all can imagine this situation ;-).

So long
Thomas

I have a png with an alpha layer and it displays correct with alpha channel
on the screen. But how can I set a specific transparency value thru
SDL_SetAlpha() (it ignores it simply). When I convert the surface to a RGB
(SDL_DisplayFormat() and not SDL_DisplayFromatAlpha()) the alpha channel is
not there and I can set the transparency value.

SDL does not support both per-surface and per-pixel alpha values at
the same time (it was deemed to be too expensive and rare an
operation), so you cannot fade an image with alpha channel

As declared in the subject I need this for some fading surfaces. I hope you
all can imagine this situation ;-).

solutions I can think of offhand:

  • use a colour key instead of alpha channel (colourkeyed blits with
    per-surface alpha are supported and can even be RLE accelerated)
    (either change your source image, or alpha-blend it onto an RGB surface
    filled with a constant colourkey value)
  • modify the alpha values of each pixel in the image manually
    (not as tricky as it sounds)

I have a png with an alpha layer and it displays correct with alpha
channel
on the screen. But how can I set a specific transparency value thru
SDL_SetAlpha() (it ignores it simply). When I convert the surface to a RGB
(SDL_DisplayFormat() and not SDL_DisplayFromatAlpha()) the alpha channel
is
not there and I can set the transparency value.

As declared in the subject I need this for some fading surfaces. I hope
you
all can imagine this situation ;-).

There’s no such function. It would mean to recompute all the alpha values.
You could probably use OpenGL, or the something like the following:--------------------------------------------------
SetAlphaFace(SDL_Surface *face, int alpha)
{
int32 i;
SDL_LockSurface(face);
Uint32 oldAlpha;
switch (face->format->BytesPerPixel)
{
case 2:
for (i = 0; i < (face->w * face->h); i++)
{
oldAlpha = *((Uint16 *)face->pixels + i) & face->format->Amask;

Uint32 newAlpha = (float)oldAlpha / 255 * alpha; //neuen Alphawert
berechnen
newAlpha &= face->format->Amask; //nur zur Sicherheit

*((Uint16 *)face->pixels + i) ^= oldAlpha;
*((Uint16 *)face->pixels + i) |= newAlpha;
}
break;

case 4:
for (i = 0; i < (face->w * face->h); i++)
{
oldAlpha = *((Uint32 *)face->pixels + i) & face->format->Amask;

Uint32 newAlpha = (float)oldAlpha / 255 * alpha; //neuen Alphawert
berechnen
newAlpha &= face->format->Amask; //nur zur Sicherheit

*((Uint32 *)face->pixels + i) ^= oldAlpha;
*((Uint32 *)face->pixels + i) |= newAlpha;
}
break;
}
SDL_UnlockSurface(face);
}

Should work, at least with 16/32 bit surfaces. Oh, and it’s irreversible, so
you have to use a copy of the original surface every time.

for (i = 0; i < (face->w * face->h); i++)

scan lines are not necessarily contiguous in memory. use surface->pitch

for (i = 0; i < (face->w * face->h); i++)

scan lines are not necessarily contiguous in memory. use surface->pitch

Thanks! Could this cause crashes, or only graphical glitches?

scan lines are not necessarily contiguous in memory. use surface->pitch

Thanks! Could this cause crashes, or only graphical glitches?

theoretically both but more likely “only” glitches.

software surfaces are created with lines aligned at 32-bit boundaries
(might be strengthened in the future), and SDL_CreateRGBSurfaceFrom()
can make surfaces with arbitrary pitch. hardware surfaces may have
pitch very different from (width * bpp) with potentially important
information interspersed

So, what is pitch exactly? Number of bytes to the next row of pixels?On Fri, 23 Mar 2001, Mattias Engdegard wrote:

scan lines are not necessarily contiguous in memory. use surface->pitch

Thanks! Could this cause crashes, or only graphical glitches?

theoretically both but more likely “only” glitches.

software surfaces are created with lines aligned at 32-bit boundaries
(might be strengthened in the future), and SDL_CreateRGBSurfaceFrom()
can make surfaces with arbitrary pitch. hardware surfaces may have
pitch very different from (width * bpp) with potentially important
information interspersed

So, what is pitch exactly? Number of bytes to the next row of pixels?

http://www.libsdl.org/faq/FAQ-General.html#GENERAL_VIDEO1

See ya,
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

On Fri Mar 23, 2001 at 11:24:55AM +0100, the boisterous
Pius II.
wrote to me:

There’s no such function. It would mean to recompute all the alpha values.
You could probably use OpenGL, or the something like the following:

I took your func and it worked, but it only fade outs (from SDL_ALPHA_OPAQUE).
When the alpha value is 0 and my function fades in, the surface is still
invisible. The alpha value is also not correct. The surface is invisible at
200 or so.

I’m new to graphic programming in general, but I know the basic semantics. The
deeper tricks are unknown to me, so how do I code the for() loop that it
takes advantage of Mattias surface->pitch suggestion?

And btw, I tried the colorkey suggestion from Mattias, but the png I try to
fade in/out has no “sharp edges” but rather a smooth transition from fully
visible in the middle to fully invisible at the border. I still hope you can
imagine that ;-). So when I try to set the alpha value of the colorkeyed
surface it worked, but the whole surface is not transparent because the smooth
transition pixels (you guessed it) has not the colorkey.

Sorry for not replying as fast as possible, but I was in my holidays and I tried
your cool function not until now.

Thanks for all your help, you guys rock!

So long
Thomas–


/\ Obviously we do not want to leave zombies around.
( ^ > - W. Richard Stevens
/ \
(
/)

You can’t use both colorkeying or full surface alpha and an alpha channel.

The alpha channel could be though of as an “analog” color key, so you don’t
really need color keying and alpha channels at the same time.

Full surface alpha + alpha channel would be very nice, though, but that would
require several multiplications per pixel (ouch!!!) with the current surface
formats. An alpha + alpha channel solution with usable performance seems to
be planned for SDL 1.3. :slight_smile:

Meanwhile, you could preprocess your images when loading them, and just pick
different versions of the same image instead of changing the surface alpha.

(Hmm… That should work for the sub-pixel accurate sprite algo I had in mind
for another Example. :slight_smile:

//David

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------> http://www.linuxaudiodev.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |--------------------------------------> david at linuxdj.com -'On Friday 30 March 2001 20:49, Thomas Krennwallner wrote:

And btw, I tried the colorkey suggestion from Mattias, but the png I try to
fade in/out has no “sharp edges” but rather a smooth transition from fully
visible in the middle to fully invisible at the border. I still hope you
can imagine that ;-). So when I try to set the alpha value of the
colorkeyed surface it worked, but the whole surface is not transparent
because the smooth transition pixels (you guessed it) has not the colorkey.