| Jonny D's Projects | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| News GigaSun Jet Tutorials C++ Projects -Beginners SDL Projects -SPriG -NFont Other Projects Contact Outside Projects
|
Tutorials
and Articles:
The Ins and Outs (and Overlays) of Alpha-blending Alpha-blending is the process of using an extra value (alpha) to combine color values (like partial transparency) instead of just replacing one with the other. Commonly in SDL, this is done with entire surfaces. One surface, the 'source', is blitted (drawn) onto another 'destination' surface (also 'dest'). Now, there are a few ways to do this and several of them are, sadly, not possible through SDL's built-in blitter (accessible through SDL_BlitSurface). I'll cover the readily possible ones first, then get to the ones that you need either Sprig or some other software for. There is a three-fold path (I'm clever) to transparency: Path 1: Colorkeying (aka CK) Path 2: Per-Surface Alpha (PSA) Path 3: Per-Pixel Alpha (PPA) All three of these can be used in various combinations to acheive visual awesomeness, with the exception that in SDL, per-pixel alpha takes priority over per-surface alpha. Colorkeying is your first choice. If you use RGB surfaces (no alpha channel) and you want some areas to be transparent and others not, then this is the way to go. First, load an image with one particular color as the background (very often people choose bright pink: RGB=255,0,255). Now, we can use SDL_SetColorKey (note the capital K)...
Colorkeying has advantages in that it is easy to use and it is processed quickly. It can only give you either full transparency or full opacity, however. The second option is per-surface alpha. This is a nice feature of SDL that allows you to control the alpha value of the entire surface all at once. This is great for certain fading effects and runs faster than per-pixel alpha. In SDL, alpha is a measure of opacity (how opaque something is). It ranges from 0 to 255 (n.b. 256 different values), 0 being fully transparent, and 255 being fully opaque. You can use SDL_SetAlpha to control your per-surface alpha...
Per-pixel alpha is found as an extra color channel on true-color surfaces, those that store color information in each pixel rather than in a palette. This is the real alpha-blending that you might normally think of. PNG (Portable Network Graphics) and TGA (Truevision Graphics Adapter, commonly 'Targa') are two common image file formats that support per-pixel alpha. There is a surprising lack of simple utilities that help you to work well with the alpha channel in images... I'm hoping to pop out one if someone doesn't beat me to it. You can load these formats with the SDL_Image library.
Now you have a few more choices... The SDL documentation has a list of the options, but a table would do much better...
Wow! There it is! Good job, self. This summarizes what you can do with transparency in SDL. There are waaay too many 'No's up there... No wonder I thought the Sprig blitter was a good idea. Look at the three columns on the right for what you want to do, then apply the appropriate flags to the source surface. Keep in mind that when performing alpha-blending in SDL, there is no way to blend the destination alpha (see Sprig). To round things out, we should chat about creating surfaces. This is done with two functions: SDL_CreateRGBSurface and SDL_CreateRGBSurfaceFrom. The first one makes a surface from scratch. The second one takes some existing pixel data and creates a new surface with it.
Now the picky stuff comes in... See all those hexidecimal values I threw in there? Those are the masks for each color channel, RGBA. Surfaces can come in all different configurations, so these values tell the blitter how to handle the data I throw at it. Each pair of characters represents 8 bits and has a max value of 255. So you can look at a single 32-bit color value like so: 0xAABBGGRR (or ABGR). I know, it looks backwards, but that's how these are represented in little endian format. Don't get me started on that. If you don't want to mess with endianess, then just use SPG_CreateAlphaSurface (again with the convenience!). You can look into SPG_CreateAlphaSurface in sprig_inline.h to see how I deal with it (or check the SDL docs). I only really mess with 32-bit images, so if you use a different format, make sure that your color masks isolate their respective color with a bit-wise AND (&). The spot where I put '50*4' is the pitch of the image. That is the number of bytes that total one horizontal scanline. In this case, 32 bits means 4 bytes, so I'm just multiplying the width by that number. The way that SDL determines if a particular surface has an alpha channel or not is by looking at its alpha mask. So, to disable the alpha channel...
Okay. That's it for built-in SDL stuff. Sprig (slowly) implements a few (slow) more (slow!) options. By pushing a flag onto the blending stack, we can change the mode of the Sprig blitter and the Sprig primitives. Oh, by the way, the blitter can be a little slow sometimes. These effects are not good for real-time usage. You should render them once before you need them, then use them wherever.
The SPG_COMBINE_ALPHA flag makes the blitter perform alpha-blending on the destination alpha channel as well as the other color channels. This is an 'overlay' effect. You can apply a partially transparent surface to a fully opaque surface and get a partially transparent result. You can apply a surface to a fully transparent dest and get a visible result. A nice set of flags are the SPG_COPY_ALPHA_ONLY and SPG_COMBINE_ALPHA_ONLY flags. You can mess with the transparency and leave the colors untouched. Check out the Sprig documentation for more. Sweet. If you want to talk more alpha to me, go ahead. Jonny D |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||