Sign in to follow this  
vrihai

How do you flip sprites with SDL?

Recommended Posts

vrihai    172
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?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
:( No other way huh. I heard you could use OpenGL Quads instead, but I'll just go with the duplicate images.

Share this post


Link to post
Share on other sites
BornToCode    1185
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[i].image); /*Register the Surface Pixel Data This Allocated Memory*/
UnlockSurface(image,i);
PlotBackward(myImage,image[i].image,i,color,side);
free(color);/*Remove it*/
color=NULL;/*Bye Bye*/
}
return myImage;
}

Share this post


Link to post
Share on other sites
vrihai    172
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.

Share this post


Link to post
Share on other sites
Koshmaar    989
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

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