# Making a transparent image in SDL

## Recommended Posts

Spippo    158
I have a little problem with an image: I have an opend window (created with SDL) and the window has a background picture, that can variate. On this background, I want to place an other picture (a black dot). So I now I want to know if it is possible to set a transparent collor? Because it only has to show the dot, and not the other pixels around it. Here's how I try to do it:
SDL_Surface *screen      // The screen surface (fully init)
SDL_Surface *background  // The background picture
SDL_Surface *ball        // The black dot

SDL_Rect rball = {160,160, 10, 10};

SDL_BlitSurface(background, NULL, screen, NULL);
SDl_BlitSurface(ball, NULL, screen, &rball);
SDl_Flip(screen);

Now I see the dot on the background, but also the surounding pixels from the ball.bmp.

##### Share on other sites
SiCrane    11839
Did you try SDL_SetColorKey()?

##### Share on other sites
Spippo    158
Can you give an example on how it works?
Because the Reference is not very clear to me (I'm not english)

##### Share on other sites
KindFred    229
The first parameter is the bitmap surface that you want to set the color key for.

The second parameter is for flags. This is set to SDL_SRCCOLORKEY.

The third parameter is an RGB value. use the SDL_MapRGB function to obtain a value for this parameter. The first parameter of the SDL_MapRGB function is the format. I would use the format member of the surface being used. the next three parameters are values for R, G, and B respectively.

In the end, it should look like this:

SDL_SetColorKey( ball, SDL_SRCCOLORKEY, SDL_MapRGB ( ball->format, 0x00, 0x00, 0x00));

Further note: I used all 0 values for the color key, you should use whatever floats your boat.

##### Share on other sites
SiCrane    11839
The basic example looks like:
SDL_Surface * surface = /* get a SDL_Surface somehow */;SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGB(surface->format, red, green, blue));

You can skip the SDL_MapRGB() if you already have the color you want to use as a transparent color in a the correct format for the surface.

##### Share on other sites
Spippo    158
hmmm, link doesn't work for me.

i've tried this:

SDL_Surface *screen      // The screen surface (fully init)SDL_Surface *background  // The background pictureSDL_Surface *ball        // The black dotbackground = SDL_LoadBMP("images/bg.bmp");ball = SDL_LoadBMP("images/ball.bmp");SDL_Rect rball = {160,160, 10, 10};SDL_Color color = {225,128,64};int SDL_SetColorKey(screen, 0, color);SDL_BlitSurface(background, NULL, screen, NULL);SDl_BlitSurface(ball, NULL, screen, &rball);SDl_Flip(screen);

And it gives me this error:

Quote:
 initializer list being treated as compound expression

##### Share on other sites
Spippo    158
if I use
Quote:
 SDL_SetColorKey(scherm, SDL_SRCCOLORKEY, SDL_MapRGB(scherm->format, 225, 128, 64));

It gives me no error, but I can still see the color that shoud be transparrent

##### Share on other sites
SiCrane    11839
SDL_SetColorKey should be applied to the surface that you want to make transparent. In your case, it looks like you should ball instead of screen.

##### Share on other sites
KindFred    229
To Clarify:
The surface you set the color key for should be the bitmap surface you are blitting to the screen.
Also:
I saw a stray 'int' in the line calling SDL_SetColorKey in your previous post.

##### Share on other sites
Spippo    158
Yeah, thanx, I should have used the ball surface, not the screen surface. (It works now).

And for the 'int': I looked at the sdl reference, and it sais:
Quote:
 #include "SDL.h"int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key);

##### Share on other sites
KindFred    229
that's what you see in the .h file. you don't need to put an int before you call the function.

*edit: what tentoid said

##### Share on other sites
tentoid    364
Quote:
Original post by Spippo
Yeah, thanx, I should have used the ball surface, not the screen surface. (It works now).

And for the 'int': I looked at the sdl reference, and it sais:
Quote:
 #include "SDL.h"int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key);

The int means that the function will return an int (integer). It will tell you if the function was successfull or failed (see the error codes from the docs). So if you want to call the function and not to check the return value just use SDL_SetColorKey(...);

##### Share on other sites
Spippo    158
It works great!!!!

For my ball, and even my paddle.

Thank you both.
You helped me realy good, and realy realy fast. (I think i'm going to rate you guys).

Spippo

##### Share on other sites
Spippo    158
Well, I have a new problem now.

The ball is moving, but it doesn't delete the previous ball, so i see a thick line across my screen. I know 3 ways to handle this problem:

- Repaint my background every time. (this takes a lot of memory and the game doesn't go smooth after a few seconds)
- Repaint a part of the background around the ball. (after 2 minutes, I still got the same problem.
- Add previous cordinates in my class and repaint only this small part of the background.

Is there another way (and better way) to do this?

Spippo

##### Share on other sites
tentoid    364
Quote:
 Original post by SpippoWell, I have a new problem now.The ball is moving, but it doesn't delete the previous ball, so i see a thick line across my screen. I know 3 ways to handle this problem:- Repaint my background every time. (this takes a lot of memory and the game doesn't go smooth after a few seconds)- Repaint a part of the background around the ball. (after 2 minutes, I still got the same problem.- Add previous cordinates in my class and repaint only this small part of the background.Is there another way (and better way) to do this?Spippo

Just use SDL_FillRect(). It's not that slow.. (use double buffering and hardware surfaces).
And just in case:
http://www.gamedev.net/community/forums/topic.asp?topic_id=284173&whichpage=1�

##### Share on other sites
Spippo    158
I can't use the FillRect, because I have an image as a background, and not just one color.

##### Share on other sites
tentoid    364
Quote:
 Original post by SpippoI can't use the FillRect, because I have an image as a background, and not just one color.

Clear.
Blit background.
Blit sprites.

Spippo    158
What do u mean?

##### Share on other sites
tentoid    364
Quote:
 Original post by SpippoWhat do u mean?

Taken from your post and modified:
SDL_FillRect(screen, NULL, 0); // fill the screen with black// draw other stuff:SDL_BlitSurface(background, NULL, screen, NULL);SDl_BlitSurface(ball, NULL, screen, &rball);// flip the buffersSDl_Flip(screen);

##### Share on other sites
KindFred    229
I believe he's talking sbout the first option you listed in your previous post, Spippo. I'm dealing with a similar problem. I don't want to redraw the entire background, then redraw the sprites on each frame. I'll post here if you haven't found a solution before me.

##### Share on other sites
Spippo    158
But then I have to draw the background every time. And that takes a lot of memory

##### Share on other sites
Woodsman    426
Quote:
 Original post by SpippoBut then I have to draw the background every time. And that takes a lot of memory
That's pretty much how things are done. Alternatively, you can save the area A of the background before blitting B to it, then blit A back at the beginning of the next time. However, depending on your machine, that might be a bit much for a ball moving around the screen. I recently worked on a multiplayer 2d space shooter with SDL, using the clear(), draw(), flip() method and it ran smoothly.

##### Share on other sites
Woodsman    426
Also, about the slowdown, if method 2 runs as slow as method 1 after a few minutes you may want to check your memory usage. That's rather indicative of a memory leak.

##### Share on other sites
KindFred    229
Thanx Woodsman, That's what I was thinking of doing, I just didn't have the time to put it into words that I or anybody else could understand. I realize that's how it's normally done ( redrawing the background, then blitting the sprites over it on each frame), but I want to give myself a challenge.

##### Share on other sites
tentoid    364
Quote:
 Original post by SpippoBut then I have to draw the background every time. And that takes a lot of memory

Did you try that? You won't probably notice any difference in the perfomance.. And it shouldn't affect memory usage. Clearing the screen is the way it should be done. Works fine in my game atleast :)

Where did you get the idea that it takes a lot of memory?