Create A Dark Picture From Another On Sdl ?


JyCet

Member
Joined
Feb 23, 2004
Messages
469
Age
118
Location
France
Website
Visit site
hi all,
today in one of my program i use 2 differents pictures to diplay some dark area on the background so my question is if I have only the normal picture of my background how generate another dark picture in a tmp sdl surface?

SDL_Surface *background;
SDL_Surface *background_dark;
background = SDL_LoadBMP("background.bmp");
// Here a programme to generate background_dark from background
... ?

thanks :)
 
JyCet posted on Aug 25 2006 at 11:37 AM said:
hi all at
today in one of my program i use 2 differents pictures to diplay some dark area on the background so my question is if I have only the normal picture of my background how generate another dark picture in a tmp sdl surface?

SDL_Surface *background;
SDL_Surface *background_dark;
background = SDL_LoadBMP("background.bmp");
// Here a programme to generate background_dark from background
... ?

thanks :)
Code:
	SDL_LockSurface(Source);
	SDL_LockSurface(Dest);
	short* SPixels = (short*)Source->pixels;
	short* DPixels = (short*)Dest->pixels;
	int SPitch = Source->pitch / 2;
	int DPitch = Dest->pitch / 2;
	for(int y=Source->w;y>-1;y--)
	{
	  short* SP = &SPixels[y * SPitch];
	  short* DP = &DPixels[y * DPitch];
	  for(int x=319;x>-1;x--)
	  {
		*DP = ((*SP) >> 1) | 0x7BEF);
		DP++;
		SP++;
	  }
	}
	SDL_UnlockSurface(Source);
	SDL_UnlockSurface(Dest);
Should do it, ofcourse the source and destination surfaces should exist, and it's not fast or anything. And surfaces should be in 16 bit mode.
 
Last edited by a moderator:
Thanks Daid,
The speed is not a pb because I would like to generate this dark background before to use it in any loop ;)

I'll test that code this evening ;)
Code:
SDL_Surface *background;
SDL_Surface *background_dark;
background = SDL_LoadBMP("background.bmp");

short* SPixels = (short*)background->pixels;
short* DPixels = (short*)background_dark->pixels;
int SPitch = background->pitch / 2;
int DPitch = background_dark->pitch / 2;
for(int y=background->w;y>-1;y--)
 {
   short* SP = &SPixels[y * SPitch];
   short* DP = &DPixels[y * DPitch];
   for(int x=319;x>-1;x--)
	{
	  *DP = ((*SP) >> 1) | 0x7BEF);
	  DP++;
	  SP++;
	 }
  }

I suppose all color are /2 here *DP = ((*SP) >> 1 ) | 0x7BEF); ?
So white (255,255,255) become gray (127,127,127)

thanks
 
Don't forget to convert your surfaces to 16bit, and make a surface for the dark version.

background_dark = SDL_CreateRGBSurface(SDL_SWSURFACE, background->w, background->h, 16, background->format->Rmask, background->format->Gmask, background->format->Bmask, background->format->Amask);


And yes, all colors are /2 there, bitshifted down with 1, and all upper bits of each color channel cut off.
 
sorry but it doesnt work :(
it create some strange color

I've found a solution with some getpixel and getpixel function
In this example I divide each color by 1.3:
Code:
Uint32 getPixel(SDL_Surface *surface, int x, int y)
{
	int bpp = surface->format->BytesPerPixel;
	 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

	 switch(bpp) {
	 case 1:
		 return *p;
	 case 2:
		 return *(Uint16 *)p;
	 case 3:
		 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
			 return p[0] << 16 | p[1] << 8 | p[2];
		 else
			 return p[0] | p[1] << 8 | p[2] << 16;

	 case 4:
		 return *(Uint32 *)p;

	 default:
		 return 0;
	 }
 }
 
void SetPixel(SDL_Surface* Surface, int x, int y, Uint32 pixel)
{
	int bpp = Surface->format->BytesPerPixel;
	Uint8 *p = (Uint8*)Surface->pixels + y * Surface->pitch + x * bpp;

	switch(bpp)
	{
	case 1:
		*p = pixel;
		break;

	case 2:
		*(Uint16*)p = pixel;
		break;

	case 3:
		if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
		{
			p[0] = (pixel >> 16) & 0xff;
			p[1] = (pixel >> 8) & 0xff;
			p[2] = pixel & 0xff;
		}

		else
		{
			p[0] = pixel & 0xff;
			p[1] = (pixel >> 8) & 0xff;
			p[2] = (pixel >> 16) & 0xff;
		}
		break;

	case 4:
		*(Uint32 *)p = pixel;
		break;
	}
}

...
// and before my loop:
bg = SDL_LoadBMP("bg3.bmp");
//bgs is my futur dark bg
drawSprite(bg, bgs, 0,0,0,0, 320, 240);
Uint32 pixel;
Uint8 r,g,b,a;
int x,y;
for(y=239;y>-1;y--)
{
 for(x=319;x>-1;x--)
 {
   pixel=getPixel(bgs,x,y);
   SDL_GetRGBA(pixel, bgs->format, &r, &g, &b, &a);
   if(r) r=r/1.3;
   if(g) g=g/1.3;
   if(b) b=b/1.3;
   pixel=SDL_MapRGBA(bgs->format, r, g, b, a);
   SetPixel(bgs,x,y,pixel);
  }
}
...
It's very slow but prefect (speedy up easy with one precalculate area for color chan)!
I've tested >>1 it's very faster (of course :)) but too dark :(

thanks for all.
 
Puzzled why it didn't work?? :blink: Are sure you are using 16bit surfaces and have init'd SDL in 16bit mode?

Also puzzled why Alpha Blending won't work for you? Can you explain what happens / doesn't happen? :blink:
 
Of course i'm in 16bits mode and 16bits surface.
I cant know why it didnt work :) ... perhaps because i work with BMP and not PNG i dont know.
That's why i've searched another solution.

If you have a better solution I suggess you to post your example code here to help everybody ;)
 
Daid posted on Aug 25 2006 at 04:41 AM said:
*DP = ((*SP) >> 1) | 0x7BEF);
That should be & 0x7BEF, of course. And if it's too dark, try ((*SP >> 1) & 0x7BEF) + ((*SP >> 2) & 0x39E7)
 
Last edited by a moderator:
Alpha works fine for me. I make a new surface, copy the image into it, make a surface that I fill with just black pixels, and blit it over the original with 50% opacity (more optimized than other levels), and use that .. after removing the scratch surfaces of course. I actually use this method to fade the current game frame and draw a debug menu over it.
 
Back
Top