Jump to content
  • Advertisement
Sign in to follow this  
KazenoZ

[SDL] Setting a colorkey on a primitive function?

This topic is 2548 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

A problem I'm running into right now;
I have a SDL_Surface* overlay, at the beginning of my code, as such:


if(overlay == NULL){overlay = SDL_CreateRGBSurface(screen->flags, screen->w,

screen->h, screen->format->BitsPerPixel, screen->format

->Rmask, screen->format->Gmask, screen->format->Bmask,

screen->format->Amask);

overlay = SDL_DisplayFormat(overlay);

boxRGBA(overlay, 0, 0, overlay->w, overlay->h, 255, 255,

255, 0);

SDL_SetAlpha(overlay, SDL_SRCALPHA, 0);

}



It's first set to NULL, and is then made to fit the screen surface, and go completely transparent, while optimizing the surface... everything's fine so far, right?

Ok, so now my problem, somewhere along the code, I have a function call to
filledEllipseRGBA(overlay, bx, by, ch.lightRadius,

ch.lightRadius, ch.lightColor.r, ch.

lightColor.g, ch.lightColor.b, ch.lightAlpha);



Which is set to magenta at that point, drawing a circle of color magenta on the screen,
Now, I want to use the SDL_SetColorKey function to set the transparent color of the overlay surface to Magenta, so that the magenta circle on the surface won't show up.

This brings up a couple of problems, it'll cause a MAJOR slow down of the game, and it wouldn't even work.
I tried positioning it first right next to the drawing function, to discover these effects, but then, even when I put it along in the initializer code at the beginning of the post, it'll still actually cause slowdown, even though it's only called once, at the beginning of the code, and not repeating...

I'm kind of at a loss here, since the surface is constantly to be changed, it isn't like using it on a static surface loaded from a file, so I'm not really sure if I'm even using the right method...


Any input would be most appreciated =)

Share this post


Link to post
Share on other sites
Advertisement
SDL_SetAlpha(overlay, SDL_SRCALPHA, 0);
If I understand correctly this makes the whole surface transparent. Is this what you want? Using SDL_SRCALPHA will normally be slower than not using it. Using a color key will also make it somewhat slower. I don't know if using both SDL_SRCALPHA and SDL_SRCCOLORKEY will be terrible slow.

Share this post


Link to post
Share on other sites
Yea, I need the whole surface to be semi transparent, and then a part of it wholy transparent, is this even possible?
Ok, so say that SRCCOLORKEY does slow it down this much, how come it only does it for shapes, and not surfaces loaded from images?

Also, why doesn't boxRGBA make the shape transparent on its' own? If I DON'T use SDL_SetAlpha after calling boxRGBA, it'll treat the shape as 100% opaque regardless of the alpha level I feed to the function)

Share this post


Link to post
Share on other sites
Can anyone atleast recommend a popular way to have runtime created surfaces have a transparent color?
On another API maybe?

Share this post


Link to post
Share on other sites
Yea, I need the whole surface to be semi transparent, and then a part of it wholy transparent, is this even possible?

Yes, made a test and this works.
#include "SDL.h"
#include "SDL_gfxPrimitives.h"
#include <stdio.h>

int main()
{
SDL_Init(SDL_INIT_VIDEO);

SDL_Surface* screen = SDL_SetVideoMode(200, 200, 0, SDL_SWSURFACE);
SDL_Surface* overlay = SDL_CreateRGBSurface(screen->flags, screen->w, screen->h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
overlay = SDL_DisplayFormat(overlay); // is this really needed?

boxRGBA(overlay, 0, 0, overlay->w, overlay->h, 255, 255, 255, 255); // Here I changed the alpha value to fully opaque
SDL_SetAlpha(overlay, SDL_SRCALPHA, 128); // Here change the alpha value to semi transparent

filledEllipseRGBA(overlay, 100, 100, 60, 60, 255, 0, 255, 255); // Here I also have to change the alpha value, otherwise this had no effect

SDL_SetColorKey(overlay, SDL_SRCCOLORKEY, SDL_MapRGB(overlay->format, 255, 0, 255)); // magenta colorkey

SDL_Rect rect = {0, 0, 0, 0};
SDL_BlitSurface(overlay, 0, screen, &rect);

SDL_Flip(screen);

SDL_Delay(4000); // get some time to see the result
SDL_Quit();
}


Ok, so say that SRCCOLORKEY does slow it down this much, how come it only does it for shapes, and not surfaces loaded from images?

If the surfaces are the same, have the same format etc. it should not make a difference how you load the surface. Using the functions provided by SDL_gfx is probably slower than blitting from a surface.

Also, why doesn't boxRGBA make the shape transparent on its' own?

boxRGBA don't affect the alpha value of the surface. The alpha value you pass to boxRGBA only affect how much of the old surface colors will be visible. Note that there is a difference between per surface alpha and per pixel alpha. SDL_SetAlpha changes the per surface alpha.

Share this post


Link to post
Share on other sites
Your example is great, but what I need is a semi transparent surface(The grey you used) with a fully transparent shape on it(Like you did with the circle), I need to be able to see the surfaces beneath it, under the effect of the tainted screen from the semi transparent color, with a bit that's completely visible of the surface below.

I only learned after posting that SDL_SRCALPHA and SDL_SRCCOLORKEY can't be used at the same time, so, atleast by the looks of it, unless there's another way to bypass this, you can't have a semitransparent shape which is per surface, and a completely transparent shape, which is per pixel with the alpha color key, used on the same surface , which explains why they kept cancelling eachother out... but that's the exactly what I needed to use, is there any way around that maybe?...

Maybe there's a function to delete a part of a drawn shape? Instead of using filledElipseRGBA to paint it to magenta and then make it transparent, a way to use a similiar function that tears away the filledElipse from the current surface, leaving it transparent?

Share this post


Link to post
Share on other sites
The grey is because the overlay surface is white and is blitted on top of the black background. The alpha value of 128 makes a mix of black and white, which is grey. The black in the middle is because of the colorkey and it is the black background you see.

If you first blit another background you will see better. Here is an example. To the left is without the overlay, to the right you see with the overlay.
overlayf.png

Share this post


Link to post
Share on other sites
Gah, I feel so stupid, I didn't even look at the values in the code after I saw the grey D:

Wow... so basicly... the big big secret behind this is just to set the initial value of the shape to completely opaque? I did it and it works like a charm now.

But there's still something wrong here, it still causes a huge slowdown when I use the SetColorKey in there. How do games that use this technique do that without dropping the frame rate?


I really appreciate your help so far, you've been very very informative and I thank you for your time =)

Share this post


Link to post
Share on other sites
I don't know how you are doing but constructing surfaces is slow so it is always good if you don't have to create new surfaces every frame. Instead try to create them all at the start and have them ready to be used when you need them.

Try pass SDL_RLEACCEL when setting the colorkey.SDL_SetColorKey(overlay, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(overlay->format, 255, 0, 255));This will probably be faster in this case (close to the speed without colorkey), but note that if you are blitting to the overlay surface after this it will be slower.

Share this post


Link to post
Share on other sites
I thought that RLE was automatically set when you use DisplayFormat()?
Also SetColorKey doesn't work if you only set it at the beginning, you need to set it each time you're using the color, but even though that is only done once, still it causes the slowdown....

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!