SFML community forums
Help => Graphics => Topic started 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.
-
IIRC you can call setScale with a negative number, e.g. sprite.setScale(1.f, -1.f);.
-
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.
-
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)).
-
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.
-
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.
-
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.
-
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)?
-
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:
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.
-
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).
-
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.
-
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.