Transparency and alpha

Hi,

I would like to load several transparent images (PNG) and blit
them on a surface. Then this surface will be blitted on the
screen. (Instead of having to blit everytime all the PNGs with
their positions directly to the screen)

I’m not able to do it… the intermediate surface is all black
or don’t show uo at all. If I blit the images directly on the
screen, everything is all right. I’ve tried a small program to
reproduce what I need :

/********************************************************/
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);

SDL_Surface *img = IMG_Load("alpha1.png");
SDL_Surface *temp = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, img->w, 
img->h, 16, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);

SDL_Rect rect = {0, img->h, 0, 0};
SDL_FillRect(screen, NULL, 7000);

// Blit the PNG on the intermediate surface
SDL_BlitSurface(img, NULL, temp, NULL);
// Blit the intermediate surface on the screen
SDL_BlitSurface(temp, NULL, screen, NULL);
// Blit the PNG on the screen below the intermediate surface
SDL_BlitSurface(img, NULL, screen, &rect);

/* we don't have the same results :( */

SDL_UpdateRect(screen, 0, 0, 0, 0);
SDL_Delay(2000);
SDL_FreeSurface(img);
SDL_FreeSurface(temp);
SDL_Quit();
/********************************************************/

Any suggestions ?

Hi,

I would like to load several transparent images (PNG) and blit
them on a surface. Then this surface will be blitted on the
screen. (Instead of having to blit everytime all the PNGs with
their positions directly to the screen)

I’m not able to do it… the intermediate surface is all black
or don’t show uo at all. If I blit the images directly on the
screen, everything is all right. I’ve tried a small program to
reproduce what I need :

/********************************************************/
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);

SDL_Surface *img = IMG_Load("alpha1.png");
SDL_Surface *temp = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, img->w,
img->h, 16, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);

The masks are for a 32 bit surface, you are requesting a 16 bit surface.
Also, I’m not sure you can rely on the surface being “cleared”, it
might contain garbage, but that shouldn’t matter in this case. And
requesting SDL_SRCALPHA is not necessary since it requests that blits
from temp should be alpha blended, but you are not doing any blits
from the temp surface.On Fri, 18 Feb 2005 05:20:34 +0000 (UTC), Mike wrote:

SDL_Rect rect = {0, img->h, 0, 0};
SDL_FillRect(screen, NULL, 7000);

// Blit the PNG on the intermediate surface
SDL_BlitSurface(img, NULL, temp, NULL);
// Blit the intermediate surface on the screen
SDL_BlitSurface(temp, NULL, screen, NULL);
// Blit the PNG on the screen below the intermediate surface
SDL_BlitSurface(img, NULL, screen, &rect);

/* we don’t have the same results :frowning: */

SDL_UpdateRect(screen, 0, 0, 0, 0);
SDL_Delay(2000);
SDL_FreeSurface(img);
SDL_FreeSurface(temp);
SDL_Quit();
/********************************************************/

Any suggestions ?


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

And
requesting SDL_SRCALPHA is not necessary since it requests that blits
from temp should be alpha blended, but you are not doing any blits
from the temp surface.

Hi and thanks for taking the time to answer !
I do 3 blits, the second one is from the intermediate(temp)
surface…

I have modified the little program, but I still can’t get
transparency from the temp surface when I blit it on the
screen… I also have a screenshot of what the program is
showing at : http://agora.ulaval.ca/~mgcou1/ss.png

////////////////////////////////////////////////////////
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);

SDL_Surface *img = IMG_Load(“alpha1.png”);
SDL_Surface *temp = SDL_CreateRGBSurface(SDL_SWSURFACE, img->w, img->h, 32, 0,
0, 0, 0);

SDL_Rect rect = {0, img->h, 0, 0};
SDL_FillRect(screen, NULL, 3000);

// Blit the image on the intermediate surface
SDL_BlitSurface(img, NULL, temp, NULL);
// Blit the intermediate surface on the screen
SDL_BlitSurface(temp, NULL, screen, NULL);
// Blit the image on the screen below the intermediate surface
SDL_BlitSurface(img, NULL, screen, &rect);

/* we don’t have the same results :frowning: */

SDL_UpdateRect(screen, 0, 0, 0, 0);
SDL_Delay(4000);
SDL_FreeSurface(img);
SDL_FreeSurface(temp);
SDL_Quit();
////////////////////////////////////////////////////////

And
requesting SDL_SRCALPHA is not necessary since it requests that blits
from temp should be alpha blended, but you are not doing any blits
from the temp surface.

Hi and thanks for taking the time to answer !
I do 3 blits, the second one is from the intermediate(temp)
surface…
Yeah sorry, I mean alpha blits, not simply blits.

I have modified the little program, but I still can’t get
transparency from the temp surface when I blit it on the
screen… I also have a screenshot of what the program is
showing at : http://agora.ulaval.ca/~mgcou1/ss.png

This is what I think is happening:

  1. temp is black after creation - either by being cleared by SDL or by
    the memory area being all zeroes.
  2. img is alpha blitted to temp using the alpha channel of img,
    meaning the black parts of temp are left untouched. Note: the alpha
    channel of temp is not touched at all!
  3. temp is blitted (not alpha blitted) to the screen, an ordinary RGB
    copy so the black parts are copied to the screen surface.
  4. since screen has been cleared to dark blue
  5. alpha blitting img to screen leaves the dark blue color shining through

What you want to do is this:

Make sure the alpha channel of the temp image is updated too, which is
NOT happening right now. That is why you get simply black background
when blitting temp to screen. Go check the docs for SetAlpha &
BlitSurface

////////////////////////////////////////////////////////
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);

SDL_Surface *img = IMG_Load(“alpha1.png”);
SDL_Surface *temp = SDL_CreateRGBSurface(SDL_SWSURFACE, img->w, img->h, 32, 0,
0, 0, 0);
As far as IOn Fri, 18 Feb 2005 13:11:55 +0000 (UTC), Mike wrote:

SDL_Rect rect = {0, img->h, 0, 0};
SDL_FillRect(screen, NULL, 3000);

// Blit the image on the intermediate surface
SDL_BlitSurface(img, NULL, temp, NULL);
// Blit the intermediate surface on the screen
SDL_BlitSurface(temp, NULL, screen, NULL);
// Blit the image on the screen below the intermediate surface
SDL_BlitSurface(img, NULL, screen, &rect);

/* we don’t have the same results :frowning: */

SDL_UpdateRect(screen, 0, 0, 0, 0);
SDL_Delay(4000);
SDL_FreeSurface(img);
SDL_FreeSurface(temp);
SDL_Quit();
////////////////////////////////////////////////////////


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

This is what I think is happening:

  1. temp is black after creation - either by being cleared by SDL or by
    the memory area being all zeroes.
  2. img is alpha blitted to temp using the alpha channel of img,
    meaning the black parts of temp are left untouched. Note: the alpha
    channel of temp is not touched at all!
  3. temp is blitted (not alpha blitted) to the screen, an ordinary RGB
    copy so the black parts are copied to the screen surface.
  4. since screen has been cleared to dark blue
  5. alpha blitting img to screen leaves the dark blue color shining through

What you want to do is this:

Make sure the alpha channel of the temp image is updated too, which is
NOT happening right now. That is why you get simply black background
when blitting temp to screen. Go check the docs for SetAlpha &
BlitSurface

This is very clear and I thank you !

But I still have some difficulties even after reading the docs to
apply concepts into code.

Maybe I don’t have yet a clear understanding of each parameters
to the key functions. That’s why I’m asking you to help me (if you
want). I don’t usually want to have the easy way with free code but
maybe this time an example will serve me better than me and the docs
alone…

Sorry for my english if you find any mistake

Thank you very much for your time,

Mike

////////////////////////////////////////////////////////
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);

SDL_Surface *img = IMG_Load(“alpha1.png”);

modified here :
SDL_Surface *temp = SDL_CreateRGBSurface(SDL_SWSURFACE, img->w, img->h, 32,
rm, bm, gm, am);

As far as I

SDL_Rect rect = {0, img->h, 0, 0};
SDL_FillRect(screen, NULL, 3000);

SDL_SetAlpha(img, 0, 0);
Did the trick apparently… and see below

// Blit the image on the intermediate surface
SDL_BlitSurface(img, NULL, temp, NULL);
// Blit the intermediate surface on the screen
SDL_BlitSurface(temp, NULL, screen, NULL);
// Blit the image on the screen below the intermediate surface

SDL_SetAlpha(img, SDL_SRCALPHA, 0);
to restore alpha blitting…

SDL_BlitSurface(img, NULL, screen, &rect);

/* we don’t have the same results :frowning: */

SDL_UpdateRect(screen, 0, 0, 0, 0);
SDL_Delay(4000);
SDL_FreeSurface(img);
SDL_FreeSurface(temp);
SDL_Quit();
////////////////////////////////////////////////////////

Thank you again !

Please ignore last post
Thank you very much again…

Mike