Sign in to follow this  
ICUP

Flipping/Mirroring a Sprite

Recommended Posts

So, I browsed through the forums and saw this: question about sprites decided to try it out and made a quick test:

//The headers
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>

Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp / 8;

    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;       /* shouldn't happen, but avoids warnings */
    }
}

void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to set */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp / 8;

    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;
    }
}

SDL_Surface *flip( SDL_Surface *original )
{
    SDL_Surface *flipped = SDL_CreateRGBSurface( SDL_SWSURFACE,original->w, original->h,
32, /* bits per pixel,change this value to whatever you want */
                           #if SDL_BYTEORDER  == SDL_LIL_ENDIAN
                            0x000000ff,
                            0x0000ff00,
                            0x00ff0000,
                            0xff000000
                           #else
                            0xff000000,
                            0x00ff0000,
                            0x0000ff00,
                            0x000000ff
                            #endif
                            );
     SDL_LockSurface( original );
     SDL_LockSurface( flipped );

     for( int x = 0 ; x < original->w ; ++x )
     {
        for( int y = 0 ; y < original->h ; ++y )
        {
            putpixel( flipped, original->w-x-1, y, getpixel( original, x, y ) );
        }
     }

     SDL_UnlockSurface( original );
     SDL_UnlockSurface( flipped );
     return flipped;
}

int main( int argc, char* args[] )
{   
	SDL_Init( SDL_INIT_EVERYTHING );

	SDL_Event tevent;
	SDL_Surface *original;
	SDL_Surface *optimized;
	SDL_Surface *flipped = NULL;
	SDL_Surface *screen;

	screen = SDL_SetVideoMode( 800, 600, 32, SDL_ANYFORMAT );

	original = IMG_Load( "RobotStationary.png" );

	optimized = SDL_DisplayFormat( original );

	SDL_Rect dstRect, flipRect2;
	dstRect.x = 0;
	dstRect.y = 0;
	flipRect2.x = original->w * 2;
	flipRect2.y = 0;

	flipped = flip( optimized );

	//////

	SDL_BlitSurface( optimized, NULL, screen, &dstRect );
	SDL_BlitSurface( flipped, NULL, screen, &flipRect2 );
	SDL_Flip( screen );



	for ( ;; )
	{
		if ( SDL_WaitEvent( &tevent ) )
		{
			if ( tevent.type == SDL_QUIT )
				break;
		}
	}

	SDL_Quit();

	return 0;
}



How come it's not working? To be honest, I don't understand the pixel manipulation stuff that much. I looked through the documentation but I have a hard time grasping stuff like pitch.

Share this post


Link to post
Share on other sites
I've never used SDL, but to flip a sprite you can simply reverse the texture coordinates. To flip horizontally, change the left and right u-coordinates. For example:

Original:
(0,0) (1,0)
(0,1) (1,1)

Flipped horizontally:
(1,0) (0,0)
(1,1) (0,1)

Repeat the process to flip vertically.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this