How do you flip sprites with SDL?

Started by
4 comments, last by Koshmaar 19 years, 5 months ago
I want to use the same sprites when a character turns. But the BlitSurface function doesn't support mirroring the way GDI Stretchblt does. Any suggestions?
Advertisement
Your going to need two seperate images to do so.
:( No other way huh. I heard you could use OpenGL Quads instead, but I'll just go with the duplicate images.
Yes it is Possible to Create a mirroring effect in SDL but you gonna have to do by copying the pixel of your original surface and plot it backward. Here is some code that i wrote to do it,for my 2d game engine. If you find Interested MaYBE You can rate me.

/*------------------------------------------------------------------------
Desc: _J_Surfaces_D21
Author:Jerome
---------------------------------------------------------------------------*/
/*A Typical Surface Use For Image Rendering*/

typedef struct _J_Surfaces_D21
{
SDL_Surface* image;
int numframes;
int lock;
int pitch;
float x,y;
int alive;
}
J_Surface,*LPJ_SURFACE;
//----------------------------------------------------------------
/*------------------------------------------------------------------------
Desc: UnlockSurface()
Author:Jerome
---------------------------------------------------------------------------*/
/*This Function Will Unlock Surfaces*/
__forceinline int __cdecl UnlockSurface(J_Surface* image,int frame)
{
if(!image[frame].image)return 0;
if(image[frame].lock==1)
SDL_UnlockSurface(image[frame].image);
return 1;
}
//--------------------------------------------------------------------
/*------------------------------------------------------------------------
Desc: LockSurface
Author:Jerome
---------------------------------------------------------------------------*/
/*This Function Will Lock Surface*/
__forceinline int __cdecl LockSurface(J_Surface* image,int frame)
{

if(SDL_MUSTLOCK(image[frame].image))
{
SDL_LockSurface(image[frame].image);
image[frame].lock=1;
}
else
image[frame].lock=0;
return 0;
return 1;
}

//------------------------------------------------------------
/*This Function Let's you Plot Data BackWards*/
__forceinline int __cdecl PlotBackward(J_Surface* image,SDL_Surface *image2,int frame,Uint32* data,int side)
{
Uint8 * bpp8=NULL;
Uint16* bpp16=NULL;
Uint32* bpp32=NULL;
Uint32 color=0;
int x=0,y=0;
int yy=0,xx=0;
if(!image[frame].image)return 0;
switch(image[frame].image->format->BitsPerPixel)
{
case 8:
LockSurface(image,frame);
for(x=0;x<image[frame].image->w;x++)
for(y=0;y<image[frame].image->h;y++)
{
bpp8=(Uint8*)image[frame].image->pixels+y*(image[frame].image->pitch)+(image[frame].image->w-1)-x;
*bpp8=data[y*(image2->w)+x];
}
UnlockSurface(image,frame);
break;
case 16:
LockSurface(image,frame);
for(x=0;x<image[frame].image->w;x++)
for(y=0;y<image[frame].image->h;y++)
{
switch(side)
{
case 0:
/*Mirror Left to Right or Right to Left*/
bpp16=(Uint16*)image[frame].image->pixels+y*(image[frame].image->pitch>>1)+((image[frame].image->w-1)-x);
break;
/*Mirror Up to Down or Down to Up*/
case 1:
bpp16=(Uint16*)image[frame].image->pixels+(((image[frame].image->h-1)-y)*(image[frame].image->pitch>>1))+x;
break;
/*Mirror in Both the Direction at the same Time*/
case 2:
bpp16=(Uint16*)image[frame].image->pixels+(((image[frame].image->h-1)-y)*(image[frame].image->pitch>>1))+((image[frame].image->w-1)-x);
break;
}
*bpp16=data[y*(image2->w)+x];/*Set the Pixel Data to the Correct Location*/
}
UnlockSurface(image,frame);
break;
case 32:
LockSurface(image,frame);
for(x=0;x<image[frame].image->w;x++)
for(y=0;y<image[frame].image->h;y++)
{
switch(side)
{
case 0:
bpp32=(Uint32*)image[frame].image->pixels+y*(image[frame].image->pitch>>2)+((image[frame].image->w-1)-x);
break;
case 1:
bpp32=(Uint32*)image[frame].image->pixels+(((image[frame].image->h-1)-y)*(image[frame].image->pitch>>2))+x;
break;
case 2:
bpp32=(Uint32*)image[frame].image->pixels+(((image[frame].image->h-1)-y)*(image[frame].image->pitch>>2))+((image[frame].image->w-1)-x);
break;
}
*bpp32=data[y*(image2->w)+x];/*Copy the Pixel*/
}
UnlockSurface(image,frame);
break;
}
return 1;
}

/*------------------------------------------------------------------------
Desc: RegisterPixelData
Author:Jerome
---------------------------------------------------------------------------*/
__forceinline Uint32* __cdecl RegisterPixelData(SDL_Surface* image)
{
Uint32* data=NULL;
Uint8 * bpp8=NULL;
Uint16* bpp16=NULL;
Uint32* bpp32=NULL;
Uint32 color=0;
int x=0,y=0;
int xx=0,yy=0;
if(!image)return NULL;
data=(Uint32*)malloc(sizeof(Uint32)*image->w*image->h);
switch(image->format->BitsPerPixel)
{
case 8:
for(x=0;x<image->w;x++)
for(y=0;y<image->h;y++)
{
bpp8=(Uint8*)image->pixels+y*(image->pitch)+x;
data[y*image->w+x]=*bpp8;
}
break;
case 16:
for(x=0;x<image->w;x++)
for(y=0;y<image->h;y++)
{
bpp16=(Uint16*)image->pixels+y*(image->pitch>>1)+x;
data[y*image->w+x]=*bpp16;
}
break;
case 32:
for(x=0;x<image->w;x++)
for(y=0;y<image->h;y++)
{
bpp32=(Uint32*)image->pixels+y*(image->pitch>>2)+x;
data[y*image->w+x]=*bpp32;
}
break;
}
return data;/*Return the Collection of Pixels*/
}
//-----------------------------------------------------
__forceinline J_Surface* __cdecl MirrorImage(J_Video *video,J_Surface* image,int side)
{
J_Surface *myImage=NULL;
Uint32 *color=NULL;
int i=0;
if(!image[0].image)return myImage;
myImage=CreateImage(video,image[0].image->w,image[0].image->h,image[0].numframes);
for(i=0;i<image[0].numframes;i++)
{
LockSurface(image,i);
color=RegisterPixelData(image.image); /*Register the Surface Pixel Data This Allocated Memory*/
UnlockSurface(image,i);
PlotBackward(myImage,image.image,i,color,side);
free(color);/*Remove it*/
color=NULL;/*Bye Bye*/
}
return myImage;
}
Hey, I'm new to C++. Just migrated from VB6. So that looks pretty complicated. I'm looking into the OpenGL method right now, but thanks anyway.
In OpenGL doing mirroring is pretty easy, just look at the code:

void SC :: Renderer :: RenderTexture(const TScrPoint & _scrPnt, usint _scrWidth, usint _scrHeight, ulint _depth,                   const TScrPoint & _texPnt, ssint _texWidth, ssint _texHeight, bool _flipH, bool _flipW) {   #ifdef __SC_DEBUG__  if (boundTexture.id == 0)   {    logError2("Renderer", "Incorrect texture.")    return;      }    #endif            // fliping if (_flipH) _texWidth = -_texWidth;  if (_flipW) _texHeight = -_texHeight;                float leftMargin = (float)_texPnt.x / (float)boundTexture.width; float rightMargin = leftMargin + (float)_texWidth/(float)boundTexture.width;  float downMargin = (float)_texPnt.y/(float)boundTexture.height; float upMargin = downMargin + (float)_texHeight / (float)boundTexture.height;                            glBegin(GL_QUADS);      glTexCoord2f(leftMargin, downMargin); 	glVertex3i(_scrPnt.x, _scrPnt.y + _scrHeight, _depth); // left down    	glTexCoord2f(leftMargin, upMargin); 	glVertex3i(_scrPnt.x, _scrPnt.y, _depth); // left up		glTexCoord2f(rightMargin, upMargin); 	glVertex3i(_scrPnt.x + _scrWidth, _scrPnt.y, _depth); // right up			          glTexCoord2f(rightMargin, downMargin); 	glVertex3i( _scrPnt.x + _scrWidth, _scrPnt.y + _scrHeight, _depth); // right down				        		        glEnd();          }


Wanna flip vertically? Just pass true as flipW. HTH

This topic is closed to new replies.

Advertisement