Problem trying to render alpha-blended sprite

I am having trouble getting an alpha-blended surface to be correctly
blended as well as set to the correct format. I have an opaque surface
(playerGraphic) and then I copy that surface to get a 50% opacity
version (playerGraphicTrans), so that I can swap between the two during
the game’s execution.

Here’s the code I use for the first surface:

SDL_SetColorKey(playerGraphic, SDL_SRCCOLORKEY | SDL_RLEACCEL, 0);
playerGraphic = SDL_DisplayFormat(playerGraphic);

This works fine. Below that is the code for the 2nd surface:

playerGraphicTrans = SDL_ConvertSurface(playerGraphic,
playerGraphic->format, playerGraphic->flags);
SDL_SetAlpha(playerGraphicTrans, SDL_SRCALPHA|SDL_RLEACCEL, 128);

This works perfectly, except that the first time I try to blit from
playerGraphicTrans, there is a small but very noticeable delay, which I
believe is the on-the-fly format conversion for that surface. So I’ve
been trying to work around that without any success. If I add this after
the last 2 lines:

playerGraphicTrans = SDL_DisplayFormatAlpha(playerGraphicTrans);

The alpha-blending disappears completely. It looks like the
DisplayFormatAlpha makes good on the “the generated surface will then be
transparent (alpha=0) where the pixels match the colourkey, and opaque
(alpha=255) elsewhere” promise, killing any 128-level alpha. No good.
Adding SDL_SetAlpha(playerGraphicTrans, SDL_SRCALPHA|SDL_RLEACCEL, 128);
after those last 3 lines of code has no effect either.

Is there no way of getting it to the correct format without a blit
first? Do I need to do some sort of false blit just to get it to set
things up? I’m running Win98, with a Geforce 2 MX 200, for what
difference it makes, but I expect this is to do with my understanding of
the API rather than the implementation. (Also, I know the above code
leaks memory - I removed various calls to SDL_FreeSurface that are in
the ‘real’ version to simplify the examples above.)–
Kylotan

I am having trouble getting an alpha-blended surface to be correctly
blended as well as set to the correct format. I have an opaque surface
(playerGraphic) and then I copy that surface to get a 50% opacity
version (playerGraphicTrans), so that I can swap between the two during
the game’s execution.

Here’s the code I use for the first surface:

SDL_SetColorKey(playerGraphic, SDL_SRCCOLORKEY | SDL_RLEACCEL, 0);
playerGraphic = SDL_DisplayFormat(playerGraphic);

This works fine. Below that is the code for the 2nd surface:

playerGraphicTrans = SDL_ConvertSurface(playerGraphic,
playerGraphic->format, playerGraphic->flags);
SDL_SetAlpha(playerGraphicTrans, SDL_SRCALPHA|SDL_RLEACCEL, 128);

This works perfectly, except that the first time I try to blit from
playerGraphicTrans, there is a small but very noticeable delay, which I
believe is the on-the-fly format conversion for that surface. So I’ve
been trying to work around that without any success. If I add this after
the last 2 lines:

i am not sure but it is because RLE “compresion” correct me if i am wrong

playerGraphicTrans = SDL_DisplayFormatAlpha(playerGraphicTrans);

The alpha-blending disappears completely. It looks like the
DisplayFormatAlpha makes good on the “the generated surface will then be
transparent (alpha=0) where the pixels match the colourkey, and opaque
(alpha=255) elsewhere” promise, killing any 128-level alpha. No good.
Adding SDL_SetAlpha(playerGraphicTrans, SDL_SRCALPHA|SDL_RLEACCEL, 128);
after those last 3 lines of code has no effect either.

Hm SDL_DisplayFormatAlpha works litlle bit different then you expect. If
you call it this way you will have memory leak. SDL_DisplayFormatAlpha
copies surface to another.
And it doesn’t work because it is copied using alpha channel. Try to
disable SDL_SRCALPHA before SDL_DisplayFormatAlpha.
Again maybe i am wrong. But this is what i read out from sources quite
long time ago.

Is there no way of getting it to the correct format without a blit
first? Do I need to do some sort of false blit just to get it to set
things up? I’m running Win98, with a Geforce 2 MX 200, for what
difference it makes, but I expect this is to do with my understanding of
the API rather than the implementation. (Also, I know the above code
leaks memory - I removed various calls to SDL_FreeSurface that are in
the ‘real’ version to simplify the examples above.)

ah it explains the memory leak :slight_smile: If you want to do this not blit it first
i suggest you would like to look at sources. IMHO SDL sources are
comprehensive.
KrataOn Fri, 26 Jul 2002, Kylotan wrote:


Kylotan


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

krata at matfyz.cz wrote:

playerGraphicTrans = SDL_ConvertSurface(playerGraphic,
playerGraphic->format, playerGraphic->flags);
SDL_SetAlpha(playerGraphicTrans, SDL_SRCALPHA|SDL_RLEACCEL, 128);

This works perfectly, except that the first time I try to blit from
playerGraphicTrans, there is a small but very noticeable delay,
which I believe is the on-the-fly format conversion for that
surface.

i am not sure but it is because RLE “compresion” correct me if i am
wrong

You’re probably right. It’s just a shame that whatever it is isn’t done
when SDL_ConvertSurface is called. I understand why lazy evaluation
might be useful but I would think it would be undesirable in most games.
Of course, I am probably just doing something wrong in the conversion.

SDL_DisplayFormatAlpha copies surface to another.
And it doesn’t work because it is copied using alpha channel. Try to
disable SDL_SRCALPHA before SDL_DisplayFormatAlpha.
Again maybe i am wrong. But this is what i read out from sources quite
long time ago.

It’s hard to keep up with all these options. There’s alpha channels and
apparently per-surface alpha and then there’s colourkeys (which appear
to be converted to and alpha channel in certain circumstances) and it
all seems a mass of special cases with minimal documentation. Can I
humbly suggest that the alpha management functions are given extra
consideration for the next version of SDL? :slight_smile:

And you’re suggesting I disable the alpha channel, but don’t I need the
alpha channel to give me my 50% opacity? Basically, I have a simple
image where I want the bits that match the colourkey to have 0% opacity
and the rest to have 50% opacity. I can’t find a way of doing this that
doesn’t incur an abrupt halt the first time it is drawn. I can get
around this with a useless blit beforehand, but I’m sure this shouldn’t
be necessary. Thanks for your help, anyway.> On Fri, 26 Jul 2002, Kylotan wrote:


Kylotan