Skip to main content

User login

What is OpenID?
  • Log in using OpenID
  • Cancel OpenID login
  • Create new account
  • Request new password
Register
  • Home
  • Browse
    • 2D Art
    • 3D Art
    • Concept Art
    • Textures
    • Music
    • Sound Effects
    • Documents
    • Featured Tutorials
  • Submit Art
  • Collect
    • My Collections
    • Art Collections
  • Forums
  • FAQ
  • Leaderboards
    • All Time
      • Total Points
      • Comments
      • Favorites (All)
      • Favorites (2D)
      • Favorites (3D)
      • Favorites (Concept Art)
      • Favorites (Music)
      • Favorites (Sound)
      • Favorites (Textures)
    • Weekly
      • Total Points
      • Comments
      • Favorites (All)
      • Favorites (2D)
      • Favorites (3D)
      • Favorites (Concept Art)
      • Favorites (Music)
      • Favorites (Sound)
      • Favorites (Textures)
  • ❤ Donate
Programming

Transparency in SDL

Buch
Friday, November 19, 2010 - 05:40
Buch's picture

How can I manage transparency in SDL? I know how to use color keying, but of course this contrasts with anti-aliasing...

  • Log in or register to post comments
Clint Bellanger
joined 15 years 7 months ago
Friday, November 19, 2010 - 05:57
Clint Bellanger's picture

Buch, when you set up a surface in SDL I think you have to choose whether it uses color keying or alpha transparency.  Then, when you draw it to another surface, the way it behaves depends on that combinations of source alpha vs. destination alpha settings.

If you're using SDL_image, when you load a file with RGBA (e.g. many PNG files) that surface will automatically have the correct alpha transparency settings, and if you draw them to the screen the edges wil work as expected.

For details, hit up the SDL documentation.  Or, if you have a specific scenario, maybe I can point you to the right SDL doc you need.

  • Log in or register to post comments
Buch
joined 14 years 8 months ago
Friday, November 19, 2010 - 06:15
Buch's picture

Thanks for the suggestion! I found something in the documentation... there's a function in the library that allows me to enable alpha channel


  • Log in or register to post comments
Tempel
joined 14 years 8 months ago
Friday, November 19, 2010 - 09:10

As a warning: my understanding is that SDL does not handle per-pixel alpha very efficiently.  If you use it too much, it'll have a noticeable framerate impact.  I know, that contrasts with antialiasing, and I don't even have any alternatives to suggest, but just be aware.

  • Log in or register to post comments
Clint Bellanger
joined 15 years 7 months ago
Friday, November 19, 2010 - 09:15
Clint Bellanger's picture

Definitely about SDL performance with per-pixel alpha.

In OSARE I had to convert all the character sprites and tilesets to "magic pink" transparency for performance.  I only use full alpha sprites for spell effects, where variable-level alpha transparency is a major part of the art.

  • Log in or register to post comments
Buch
joined 14 years 8 months ago
Friday, November 19, 2010 - 09:25
Buch's picture

Actually I'm just making some trials to learn SDL, but at the moment I haven't found any slow-down and I'm getting a much better result than with color keying... 


  • Log in or register to post comments
Pompei2
joined 15 years 5 months ago
Friday, November 19, 2010 - 09:43
Pompei2's picture

I back that up too, if you use a lot of it it will get slow as hell. There was something called glSDL that used OpenGL as a rendering backend for SDL that avoided this slowdown but I don't know what's the current state of it. You might want to search the mailing lists.

  • Log in or register to post comments
Pompei2
joined 15 years 5 months ago
Wednesday, December 1, 2010 - 06:01
Pompei2's picture

You could try SFML it is not only more simple than SDL but it is also faster ;-) I have been using it since a few days now and it looks great (and does full transparency). It relies on OpenGL, you can see this as a huge advantage or huge drawback.

  • Log in or register to post comments
Buch
joined 14 years 8 months ago
Tuesday, May 10, 2011 - 11:19
Buch's picture

I'm having a problem still with transparency: when I use the function SDL_CreateRGBSurface to create an empty surface, how can I make it completely transparent? I tried changing the mask values: giving an alpha mask value of 0xFF000000 as suggested by the documentation creates an empty and transparent surface, but when I blit anything on it the surface remains empty.


  • Log in or register to post comments
Buch
joined 14 years 8 months ago
Tuesday, May 10, 2011 - 11:20
Buch's picture

I'm having a problem still with transparency: when I use the function SDL_CreateRGBSurface to create an empty surface, how can I make it completely transparent? I tried changing the mask values: giving an alpha mask value of 0xFF000000 as suggested by the documentation creates an empty and transparent surface, but when I blit anything on it the surface remains empty.


  • Log in or register to post comments
Anonymous (not verified)
joined 0 sec ago
127.0.0.1
Tuesday, May 10, 2011 - 11:25

Buch, can you post your example code to e.g. pastebin?

  • Log in or register to post comments
Buch
joined 14 years 8 months ago
Tuesday, May 10, 2011 - 11:33
Buch's picture

It's a short piece of code , so I'll just post it here... Thanks for your interest

This is inside a class; frameWidth and frameHeight are the values of the size of the image; I've skipped the part where I blit images on the surface created because there is a lot of code there to choose which image blit and how to do it, but I'm pretty sure the problem is not there, because when I do it outside from this function on an image not made with SDL_CreateRGBSurface (such as the window) I don't have any problem.

SDL_Surface* image(){

SDL_Surface* result = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, frameWidth, frameHeight, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);

//Here I just blit an image on the surface...

return result;

}

 


  • Log in or register to post comments
Clint Bellanger
joined 15 years 7 months ago
Tuesday, May 10, 2011 - 13:12
Clint Bellanger's picture

Note that what happens with the Alpha depends on both the source and destination surfaces.

From the SDL documentation:

The results of blitting operations vary greatly depending on whether SDL_SRCAPLHA is set or not. See SDL_SetAlpha for an explaination of how this affects your results. Colorkeying and alpha attributes also interact with surface blitting, as the following pseudo-code should hopefully explain.


if (source surface has SDL_SRCALPHA set) {
if (source surface has alpha channel (that is, format->Amask != 0))
blit using per-pixel alpha, ignoring any colour key
else {
if (source surface has SDL_SRCCOLORKEY set)
blit using the colour key AND the per-surface alpha value
else
blit using the per-surface alpha value
}
} else {
if (source surface has SDL_SRCCOLORKEY set)
blit using the colour key
else
ordinary opaque rectangular blit
}

  • Log in or register to post comments
Buch
joined 14 years 8 months ago
Wednesday, May 11, 2011 - 04:38
Buch's picture

The problem is not that blitting on the surface doesn't work properly, but that the surface created with SDL_CreateRGBSurface is black and opaque if amask is 0 or remains completely transparent (even if I blit something on it) if amask is 0xFF000000.

What I would like to do is creating a transparent surface (I mean that all pixels are transparent, not that the per-surface alpha is transparent).

I've tried this:

Uint32 background = SDL_MapRGBA(result->format, 0,0,0,SDL_ALPHA_TRANSPARENT);

SDL_FillRect(result, &result->clip_rect, background);

to make all the pixels transparent, but the per-pixel alpha doesn't change, while the color does (if I change the values of RGB the black rectangle becomes a colored rectangle).

Sorry if I can't explain this very well...

Thank you for your interest anyway


  • Log in or register to post comments
Buch
joined 14 years 8 months ago
Wednesday, May 11, 2011 - 05:46
Buch's picture

Problem solved (at least I think so...)

I had a look once more at the docs and found out that the SDL_BlitSurface function doesn't copy the alpha values from the source to the destination; then I wrote a function that copies pixel pixel from the source to the destination, including alpha values, and it works.

Thank you for your help.


  • Log in or register to post comments
aerosum
joined 12 years 3 months ago
Wednesday, January 16, 2013 - 23:07

Hey guys, I got a lot of insight from the discussion above. But there still a problem I am facing with my code. What I am doing is that I am creating a raw buffer through another code which decodes a PNG image and fills it into the buffer. Then I create a SDL_Surface over that buffer using SDL_CreateRGBSurfaceFrom function.

Now when I display the image on the screen I do not see the alpha values blending properly. Any Suggestions?

What I do is like:

void * ImgBuffer = ReadPNG("FILE.png"); // Creates a raw buffer with Decoded PNG.

SDL_Surface *image = SDL_CreateRGBSurfaceFrom(ImgBuffer, SWSURFACE, w, h, 32, w*4, 0x00000000, 0x00000000, 0x00000000, 0x00000000);

SDL_Rect rect = {0, 0, 100, 100}; // since the image size is 100x100

SDL_BlitSurface(SDL_Screen /*Video Screen*/, NULL, image, &rect);

 

But this doesn't show the image properly with alpha blending

 

Any help would be great

  • Log in or register to post comments
leeor_net
joined 14 years 11 months ago
Thursday, January 17, 2013 - 04:49
leeor_net's picture

You're not specifying an alpha mask. Despite what the documentation says (and it can be a bit confusing), if you don't specify an alpha mask, you won't get any alpha channel at all. Your call to SDL_CreateRGBSurfaceFrom should look like this:

unsigned int rmask = 0, gmask = 0, bmask = 0, amask = 0;

if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
{
    rmask = 0x000000ff;
    gmask = 0x0000ff00;
    bmask = 0x00ff0000;
    amask = 0xff000000;
}
else
{
    rmask = 0xff000000;
    gmask = 0x00ff0000;
    bmask = 0x0000ff00;
    amask = 0x000000ff;
}

SDL_Surface* srf = SDL_CreateRGBSurfaceFrom(buffer, SDL_SWSURFACE, w, h, 32, w*4, rmask, gmask, bmask, amask);

  • Log in or register to post comments
bart
joined 13 years 10 months ago
Thursday, January 17, 2013 - 05:16
bart's picture

Just a note on per-pixel alpha in SDL.  I feel like there's some option where you can choose whether to render in hardware or in software, and (counterintuitively) software is way faster for per-pixel alpha.

  • Log in or register to post comments
Clint Bellanger
joined 15 years 7 months ago
Thursday, January 17, 2013 - 13:54
Clint Bellanger's picture

(the following only applies to SDL 1.2 or earlier).

Note that in Flare we solved this issue by borrowing a function from SDL_gfx that correctly blits one alpha surface to another. The two files are:

  • SDL_gfxBlitFunc.c
  • SDL_gfxBlitFunc.h

The function name is SDL_gfxBlitRGBA. Note it's done in software so it's slow.

  • Log in or register to post comments