Semi-transparency


motorollin

Member
Joined
Jul 31, 2007
Messages
163
I want the screen to flash white and then gradually fade back to the game. I have Googled it and the answer seems to be SDL_SetAlpha(surface, SDL_SRCALPHA, transparency) but when I try this I get "expected constructor, destructor, or type conversion before '(' token " and "expected `,' or `;' before '(' token". Can anyone point me towards the correct command so I can look up the syntax and how to use it? I can write a routine which adjust the transparency each frame to give the effect of fading, I just don't know the command/syntax to actually set the surface transparency.

BTW I'm assuming transparency on the surface will affect SDL_Rects as well as sprites?
 
You already have the correct command.
It's SDL_SetAlpha and your problem is probably a syntax error on the previous line.
 
motorollin said:
...
BTW I'm assuming transparency on the surface will affect SDL_Rects as well as sprites?

What do you mean with that?
SDL_Rects don't store any graphical info, so they won't be affected by alpha.
And loaded sprites get stored into a surface, so if you apply alpha to that surface (a sprite sheet?) it will affect all sprites cut out with SDL_Rects.
 
Last edited by a moderator:
Well the previous line is "SDL_Surface *screen = NULL;", nothing wrong there that I can see. I also just downloaded SDL_gfx and included SDL_gfxPrimitives.h, then replaced the Set_Alpha line with "boxRGBA( *screen, 0, 0, 320, 240, 255, 255, 255, 255 )" but got the same error as before 0_o

[EDIT]
Ok I moved the command after the background surface is applied and it compiles now. But it doesn't do what I expected it to. As a test I did "SDL_SetAlpha(background, SDL_SRCALPHA, 255) thinking that would make the surface containing my game's backdrop totally transparent, but all it did was make the sprites smear across the still-visible background :blink:
[/EDIT]
 
[EDIT2]
Also just tried "boxRGBA( background, 0, 0, 320, 240, 255, 255, 255, 255 );" after the background surface is applied and got "[Linker error] undefined reference to `_imp__boxRGBA'". I opened the Dev-Cpp example project provided with SDL_Gfx and checked its linker settings and couldn't see anything different to mine.
[/EDIT2]
 
Well it appears it does work, it just causes weird effects if sprites are blitted over the alpha-adjusted layer. I don't know how to get around this, but it's not a problem for me since my white flash will be on top of everything else. So in my case the solution was to create a new layer on top of everything else and adjust its transparency:

CODE
SDL_Surface *bomb = NULL;
bomb = load_image( "bomb.png" );
apply_surface( 0, 0, bomb, screen, &camera );
SDL_SetAlpha( bomb, SDL_SRCALPHA, 100 );


The SetAlpha commands will be moved to a function which is triggered when a certain key is pressed, and the actual value applied as the alpha level will gradually decrease each frame to give the fade effect.
 
Just a note that Alpha stuff generally causes slowdown on the 2X... dpending on use of course.

So be careful! Obviously see how you go... but if things look sluggish, then it might be alpha-blending that's to blame...
 
Yes I have noticed that the effect is quite slow, but the game speeds up again once it has finished so it's not too bad since you can't see much on screen during the effect anyway.

Am I correct in thinking that there is now a HW accelerated version of SDL for the GP2X? Would that help?
 
You are probably already using HWAccel SDL already. It's in most of the libs you can get around here!

It makes blitting sprites faster... I don't believe it does much for alpha-blends...

Basically if you use HWSurfaces then they are HW acelerated :)

You should be able to notice an improvement on the 2X
 
Is there any way I can pre-render sprites at varying degrees of transparency and then blit them one after the other? Or would this cause the same performance hit by virtue of the fact that they are transparent?
 
motorollin said:
Is there any way I can pre-render sprites at varying degrees of transparency and then blit them one after the other? Or would this cause the same performance hit by virtue of the fact that they are transparent?
I don't know much about programming, but you could store the sprites as PNG files could you not? They support transparency.
 
Last edited by a moderator:
The problem is that the SDL imaging layer would still have to claculate the alpha when the png or precalced (more like preprepared) Surface are renderred.

I'm not sure what the best solution is. But you could try to have one transparent colour and manually, in photoshop have sprites which are faded to the strongest background colour... I'm not sure how to explain this better.
 
Alpha is always slow if done in software, because it requires breaking every pixel into colour components, mixing component from source to destination by the alpha amount, and setting the target. ie: A normal copy from source to dest is just a copy .. easy. An alpha is breaking up to colour components on source and dest, some math on them, and then the copy. Tonnes more work.

jeff
 
So how is it that games like Payback have such complex lighting and transparency effects with no slowdown? Are they written in a lower level language to bash the hardware directly? I wouldn't be surprised if this is the case since the game was written by Amiga coders ;)

In any case, the slowdown isn't too bad and as I said you can't really see what's happening on the screen while the effect is in progress.
 
The team had prior experience with systems such as Amiga and also more relative, the GBA. They wrte their game engine from scratch not using any liibs like SDL. They probably have there own nicey optimised code for rendering blend effects.
 
motorollin said:
I want the screen to flash white and then gradually fade back to the game.
There has to be a faster way to do this than with alpha, though perhaps it might take directly fiddling with hardware registers. :/ Maybe something with the gamma tables?
 
Last edited by a moderator:
Given the hardware I think your best bang for the buck would be some really cheesy palette effects, like how everything goes green when you get slimed in Frogs of War. Though that's eight bit color, wonder how it would fly at 16 or 24.

CODE

void loadbmp( SDL_Surface *surface, char *fname, int load_palette )
{
int i;
SDL_Surface *image = NULL;
image = SDL_LoadBMP( fname );

if (image == NULL)
{
fprintf(stderr, "Error loading %s: %s\n", fname, SDL_GetError());
exit( 0 );
}

if (image->format->palette && surface->format->palette)
{
if ( load_palette ) // set up palette effects
{
for ( i = 0; i < 256; i++ )
{
// default
Colors[ 0 ][ i ].r = image->format->palette->colors[ i ].r;
Colors[ 0 ][ i ].g = image->format->palette->colors[ i ].g;
Colors[ 0 ][ i ].b = image->format->palette->colors[ i ].b;

// red
Colors[ 1 ][ i ].r = image->format->palette->colors[ i ].r;
Colors[ 1 ][ i ].g = image->format->palette->colors[ i ].g / 4;
Colors[ 1 ][ i ].b = image->format->palette->colors[ i ].b / 4;

// green
Colors[ 2 ][ i ].r = image->format->palette->colors[ i ].r / 4;
Colors[ 2 ][ i ].g = image->format->palette->colors[ i ].g;
Colors[ 2 ][ i ].b = image->format->palette->colors[ i ].b / 4;

// blue
Colors[ 3 ][ i ].r = image->format->palette->colors[ i ].r / 4;
Colors[ 3 ][ i ].g = image->format->palette->colors[ i ].g / 4;
Colors[ 3 ][ i ].b = image->format->palette->colors[ i ].b;
}
}
SDL_SetColors(surface, image->format->palette->colors, 0, image->format->palette->ncolors);
}
if ( SDL_BlitSurface(image, NULL, surface, NULL) < 0 )
fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());

SDL_UpdateRect(surface, 0, 0, 0, 0);
SDL_FreeSurface(image);
}
void setPaletteColor( SDL_Surface *surface, short pallete )
{
SDL_LockSurface( surface );
SDL_SetColors(surface, Colors[ pallete ], 0, 256 );
SDL_UnlockSurface( surface );
}
 
Back
Top