SFML community forums

Help => Graphics => Topic started by: pwnstar23 on December 29, 2012, 01:07:38 am

Title: SFML2 nightly how to flip a Sprites Texture?
Post by: pwnstar23 on December 29, 2012, 01:07:38 am
What is the proper way to flip a sprites texture without moving the sprite?

I have a single texture, and two sprites that reference it.

I want one of these sprites to display the texture flipped.  This is so it looks like they connect when placed together.

Edit I mean flipped on the Y axis.
Title: Re: SFML2 nightly how to flip a Sprites Texture?
Post by: eXpl0it3r on December 29, 2012, 01:22:24 am
IIRC you can call setScale with a negative number, e.g. sprite.setScale(1.f, -1.f);.
Title: Re: SFML2 nightly how to flip a Sprites Texture?
Post by: pwnstar23 on December 29, 2012, 01:47:12 am
hmm I tried what you said, but now there is just black where the texture should be, I think this is because it's drawing it up and to the right, instead of down and to the right.
Title: Re: SFML2 nightly how to flip a Sprites Texture?
Post by: Laurent on December 29, 2012, 09:40:12 am
Negative scale should work, but it moves the sprite.

The only solution that doesn't touch the sprite's transformation at all, is to use a textureRect with a negative height (sf::IntRect(0, height, width, -height)).
Title: Re: SFML2 nightly how to flip a Sprites Texture?
Post by: pwnstar23 on January 02, 2013, 03:40:12 am
Thank you for your replies.  In case anyone has a simular issue I'll post a solution I found. 

It isn't ideal from a memory standpoint but it does work.  Load your image as an sf::Image
then flip it using the method, and then load it into a texture.  Texture will copy it into a field.

sf::Image upsideDownImage;
   upsideDownImage.loadFromFile( "someImageFile.jpg" );
   upsideDownImage.flipVertically();

   mBackgroundTexUpsideDown.loadFromImage( upsideDown );

So this means you have to have 2 images in memory, even though they are the same image just flipped.  And also flip and copy operations that take some time.  You don't have to keep the original sf::Image around since sf::Texture copies it into a field.
Title: Re: SFML2 nightly how to flip a Sprites Texture?
Post by: pwnstar23 on January 02, 2013, 03:49:16 am
Negative scale should work, but it moves the sprite.

The only solution that doesn't touch the sprite's transformation at all, is to use a textureRect with a negative height (sf::IntRect(0, height, width, -height)).

This doesn't appear to work, I just get the streaks for an image, where the pixels are the same as the first one across the entire image.
Title: Re: SFML2 nightly how to flip a Sprites Texture?
Post by: masskiller on January 02, 2013, 04:57:57 am
Thank you for your replies.  In case anyone has a simular issue I'll post a solution I found. 

It isn't ideal from a memory standpoint but it does work.  Load your image as an sf::Image
then flip it using the method, and then load it into a texture.  Texture will copy it into a field.

sf::Image upsideDownImage;
   upsideDownImage.loadFromFile( "someImageFile.jpg" );
   upsideDownImage.flipVertically();

   mBackgroundTexUpsideDown.loadFromImage( upsideDown );

So this means you have to have 2 images in memory, even though they are the same image just flipped.  And also flip and copy operations that take some time.  You don't have to keep the original sf::Image around since sf::Texture copies it into a field.

Granted that's a good solution, but impractical in a real-time implementation as texture binding isn't something trivial timewise. There shouldn't be much of a memory issue with it unless the image is big. If you need to use the flipped ones often you can just add the images (assuming it's for an animation and that it doesn't exceed too much in size) in the sprite sheet.
Title: Re: SFML2 nightly how to flip a Sprites Texture?
Post by: Laurent on January 02, 2013, 07:57:24 am
Quote
This doesn't appear to work, I just get the streaks for an image, where the pixels are the same as the first one across the entire image.
Are you sure that you used sf::IntRect(0, height, width, -height) and not sf::IntRect(0, 0, width, -height)?
Title: Re: SFML2 nightly how to flip a Sprites Texture?
Post by: Ancurio on January 03, 2013, 07:40:00 am
I don't know if it's really efficient or not, but the way I recently solved flipped textures was in my shader,
something like:
Code: [Select]
vec2 coor = gl_TexCoord[0].xy;
if (flip)
coor.x = (1.0 - coor.x);
gl_FragColor = texture2D(texture, coor);

for horizontal flipping.

The nice thing about this was that I didn't have to fiddle with any Sprite related stuff
(changing the state before drawing, and restoring it afterwards),
and just set a little parameter in my sprite shader.
Title: Re: SFML2 nightly how to flip a Sprites Texture?
Post by: Laurent on January 03, 2013, 07:59:15 am
Quote
I don't know if it's really efficient or not, but the way I recently solved flipped textures was in my shader
It's probably overkill if you don't already have a fragment shader. And it doesn't work if the sprite uses a sub-rectangle of the texture (at least without additional parameters).
Title: Re: SFML2 nightly how to flip a Sprites Texture?
Post by: pwnstar23 on January 03, 2013, 08:39:25 am
Thank you for your replies.  In case anyone has a simular issue I'll post a solution I found. 

It isn't ideal from a memory standpoint but it does work.  Load your image as an sf::Image
then flip it using the method, and then load it into a texture.  Texture will copy it into a field.

sf::Image upsideDownImage;
   upsideDownImage.loadFromFile( "someImageFile.jpg" );
   upsideDownImage.flipVertically();

   mBackgroundTexUpsideDown.loadFromImage( upsideDown );

So this means you have to have 2 images in memory, even though they are the same image just flipped.  And also flip and copy operations that take some time.  You don't have to keep the original sf::Image around since sf::Texture copies it into a field.

Granted that's a good solution, but impractical in a real-time implementation as texture binding isn't something trivial timewise. There shouldn't be much of a memory issue with it unless the image is big. If you need to use the flipped ones often you can just add the images (assuming it's for an animation and that it doesn't exceed too much in size) in the sprite sheet.

It's only done during the loading, not during the real time loop so performance isn't effected just load times slightly.
Title: Re: SFML2 nightly how to flip a Sprites Texture?
Post by: pwnstar23 on January 04, 2013, 03:07:31 am
Quote
This doesn't appear to work, I just get the streaks for an image, where the pixels are the same as the first one across the entire image.
Are you sure that you used sf::IntRect(0, height, width, -height) and not sf::IntRect(0, 0, width, -height)?
Yea this seems to work!  Much better solution thank you.