Hi all,
I’m wanting to get a snapshot of the screen that I’ve drawn (I get this out of
the back buffer, and it works OK since I’m working purely on event-driven
things). But then I want to halve the brightness of each pixel, then blit
another image over the top of that.
At present, I’ve got a nested loop structure to go over the whole screen, and
it shifts the pixel value, masks it, and then tries to put it back onto the
screen. Only it doesn’t work. Here’s the code (dest is the SDL_Surface
pointer that is the back buffer):
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
int width = dest->w;
int height = dest->h;
Uint8 colourdepth = dest->format->BitsPerPixel;
SDL_Surface * buffer = SDL_CreateRGBSurface(SDL_HWSURFACE, width, height,
colourdepth, rmask, gmask, bmask, amask);
SDL_LockSurface(dest);
SDL_Rect fill;
fill.h = fill.w = 1;
for(int j=0 ; j<height ; ++j) {
fill.y = j;
for(int i=0 ; i<width ; ++i) {
Uint8 * srcptr = (Uint8*)(dest->pixels);
srcptr += ydest->pitch;
srcptr += xdest->format->BytesPerPixel;
fill.x = i;
Uint32 pixel = ((Uint32)srcptr);
Uint32 gpixel = pixel | dest->format->Gmask;
Uint32 rpixel = pixel | dest->format->Rmask;
Uint32 bpixel = pixel | dest->format->Bmask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
gpixel = (gpixel >> 1) | dest->format->Gmask;
rpixel = (rpixel >> 1) | dest->format->Rmask;
bpixel = (bpixel >> 1) | dest->format->Bmask;
#else
gpixel = (gpixel << 1) | dest->format->Gmask;
rpixel = (rpixel << 1) | dest->format->Rmask;
bpixel = (bpixel << 1) | dest->format->Bmask;
#endif
Uint32 newpixel = gpixel | rpixel | bpixel;
SDL_FillRect(buffer, &fill, newpixel);
}
}
SDL_UnlockSurface(dest);
(buffer is blitted to dest a bit later on after a few other things)
I have a few questions about this:
- Would what I want to do work with alpha blending? I have no idea how to use
alpha blending and haven’t found a satisfactory explanation of how it works
despite lots of searching - Have I got the shifting right for little-endian machines, in that I shift
right and not left? - Is there something other than the SDL_FillRect that might be a better choice
to make this work? - Can anyone see why this doesn’t work?
- If anyone has a better algorithm, I’d really, really like to know what it is
(especially if it works!).
TIA,
-J