How do you flip sprites with SDL?
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?
:( 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;
}
/*------------------------------------------------------------------------
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:
Wanna flip vertically? Just pass true as flipW. HTH
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
Popular Topics
Advertisement