Bliting with alpha channel reloaded

Hallo.

It’s probably mine misunderstanding of docs, but I have troubles with
creating surface with some alpha pixels and bliting it to screen.

I’ll reduce chit-chat to source code, if you don’t mind. Strip down to it
basis, code looks like this:
/* CODE */

// Set mode
pScreen = SDL_SetVideoMode(1024,768,32, SDL_HWSURFACE | SDL_HWPALETTE |
SDL_DOUBLEBUF);

// Load one big png with all game sprites
pSprites = IMG_Load(“MyAllSpriteImageWithTrasparentChannel.png”);

// Create single sprite surface
// I want to use alpha channel when bliting from this surface
(SDL_SRCALPHA).
// pSprites->format->Amask != 0
pSprite = SDL_CreateRGBSurface(SDL_HWSURFACE | SDL_SRCALPHA, SPR_WIDTH,
SPR_HEIGHT, pSprites->format->BitsPerPixel, pSprites->format->Rmask,
pSprites->format->Gmask, pSprites->format->Bmask, pSprites->format->Amask);

// Select region from all_game_sprites surface and blit it to single sprite
SDL_Rect clipRect;
clipRect = …;
SDL_BlitSurface(pSprites,&clipRect,pSprite,NULL);

// HERE I PLAN TO APPLY SOME TRANSFORMATIONS
// … rotate sprite, create stains (sprites are pieces of wood)
// … but for now its nop

// Blit to screen
SDL_BlitSurface(pSprite,NULL,pScreen);

/* EDOC */

… problem is that nothing is blit. I wanted to draw to screen as written
in SDL docs SDL_BlitSurface:

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 color key

When I set Amask to 0 image sprite is blited correctly but w/o alpha channel
:frowning: I can’t use color keys, because sprite image have more than 1 bit alpha
channel and I want to keep it (frame rate is not crucial for me).

Imho this note from SDL docs SDL_SetAlpha applies to my case. But hell… I
don’t understand it;-(
"
Note that RGBA->RGBA blits (with SDL_SRCALPHA set) keep the alpha of the
destination surface. This means that you cannot compose two arbitrary RGBA
surfaces this way and get the result you would expect from “overlaying"
them; the destination alpha will work as a mask.

Thank you very much for advice.

Best regards

Adam

PS: if this message comes twice sry, i m just noob :-(–
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.1.375 / Virus Database: 268.2.1/279 - Release Date: 10. 3. 2006

It’s probably mine misunderstanding of docs, but I have troubles with
creating surface with some alpha pixels and bliting it to screen.

You don’t need to copy the sub-rects of your sprite atlas into
individual SDL_Surfaces before blitting them. Just blit the rectangle
you need from the big surface into the screen.

    --Gabriel________________________________________________________________________

Gabriel Gambetta
Mystery Studio - http://www.mysterystudio.com
Gabriel on Graphics - http://gabrielongraphics.blogspot.com

It’s probably mine misunderstanding of docs, but I have troubles with
creating surface with some alpha pixels and bliting it to screen.

You don’t need to copy the sub-rects of your sprite atlas into
individual SDL_Surfaces before blitting them. Just blit the rectangle
you need from the big surface into the screen.

Actually I would like create multiple sprite instances, each with own set
transformations prepared at application init.

E.g. master image contains image of letter “A” and I would like to have
three sprites prepared after app init: one “A” rotated to the left, one "A"
rotated to the right and one “A” with old coffee stain on it (blited stain
surface with some alpha over sprite surface^_^)

As a workaround I’ve spitted master image to individual sprites and I use
IMG_Load instead of SDL_CreateSurface and SDL_BlitSurface. But this solution
is bit awkward (it was copy-paste hell in a gimp^_^ and still I don’t know
if it works with that stain-thing)

Regards
Adam–
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.1.375 / Virus Database: 268.2.1/279 - Release Date: 10. 3. 2006

Imho this note from SDL docs SDL_SetAlpha applies to my case. But hell… I
don’t understand it;-(
"
Note that RGBA->RGBA blits (with SDL_SRCALPHA set) keep the alpha of the
destination surface. This means that you cannot compose two arbitrary RGBA
surfaces this way and get the result you would expect from “overlaying"
them; the destination alpha will work as a mask.

If you remember that newly created surfaces are fully transparent (alpha
channel = 0) and that blitting does not change the destination alpha you
get what you got.

The reason for not blendning the alpha channel is that I can think of
several diffrent ways of blendning them, all giving very diffrent results.
And since the simplest way to get the correct result is to blit
everything to the screen in layers anyway, I dont think anyone will be
spending a lot of time implementing it.

But I’m thinking about supplying a SDL_CopySurface patch for SDL 1.3 if I
get some time over.On Sun, 12 Mar 2006, adam wrote:

As a workaround I’ve spitted master image to individual sprites and I use
IMG_Load instead of SDL_CreateSurface and SDL_BlitSurface. But this solution
is bit awkward (it was copy-paste hell in a gimp^_^ and still I don’t know
if it works with that stain-thing)

In that case you should remove the SDL_SRCALPHA flag, blit, and restore
the SDL_SRCALPHA flag. I think that does what you want to do. In fact I
have that function already :

static void __copyPixels (SDL_Surface* pSrc, SDL_Surface* pDst, int nX,
int nY, int nW, int nH, int nDX, int nDY)
{
int nOrigFlag = pSrc->flags;
int nOrigAlpha = pSrc->format->alpha;
int nOrigCK = pSrc->format->colorkey;

SDL_SetAlpha(pSrc, 0, 255);
SDL_SetColorKey(pSrc, 0, 0);

SDL_Rect pSrcRect;
pSrcRect.x = nX;
pSrcRect.y = nY;
pSrcRect.w = nW;
pSrcRect.h = nH;

SDL_Rect pDstRect;
pDstRect.x = nDX;
pDstRect.y = nDY;

SDL_BlitSurface(pSrc, &pSrcRect, pDst, &pDstRect);

if (nOrigFlag & SDL_SRCALPHA)
	SDL_SetAlpha(pSrc, SDL_SRCALPHA, nOrigAlpha);

if (nOrigFlag & SDL_SRCCOLORKEY)
	SDL_SetColorKey(pSrc, SDL_SRCCOLORKEY, nOrigCK);

}

    --Gabriel________________________________________________________________________

Gabriel Gambetta
Mystery Studio - http://www.mysterystudio.com
Gabriel on Graphics - http://gabrielongraphics.blogspot.com