Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: setScale flipping weird graphics  (Read 1805 times)

0 Members and 1 Guest are viewing this topic.

Cervby

  • Newbie
  • *
  • Posts: 3
    • View Profile
setScale flipping weird graphics
« on: April 25, 2014, 03:03:39 pm »
The graphics looks strange when I try to flip an image using setScale().

My tileset:


This is what it looks like when I run it:


This is what it should look like:


My code:
#include <SFML/Graphics.hpp>

const int tilemap_tilewidth = 4;
const int tilemap_tileheight = 2;
const int tilesize_x = 32;
const int tilesize_y = 32;
const int mapwidth = 128;
const int mapheight = 128;
const int mapwidth_in_tiles = mapwidth / 32;
const int mapheight_in_tiles = mapheight / 32;

struct tile
{
        bool flip_x;
        bool flip_y;
        int index;
};

struct tile tilemapdata [mapheight_in_tiles][mapwidth_in_tiles] =
{
        {{0, 0, 0}, {0, 0, 0}, {0, 0, 1}, {0, 0, 2}},
        {{0, 0, 3}, {0, 0, 7}, {1, 0, 3}, {0, 1, 7}},
        {{0, 0, 1}, {0, 0, 2}, {1, 0, 1}, {0, 0, 0}},
        {{0, 0, 1}, {0, 0, 2}, {1, 0, 4}, {1, 0, 3}}
};


int main()
{
    sf::RenderWindow window(sf::VideoMode(128, 128), "SFML Game");
       
        sf::Texture tilemap;
        if (!tilemap.loadFromFile("Resources/tileset.png"))
        {
                return -1;
        }

        sf::Sprite currenttile;
        currenttile.setTexture(tilemap);
        currenttile.setOrigin(sf::Vector2f(tilesize_x / 2, tilesize_y / 2));

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

                window.clear();
               
                for(int y = 0; y < mapheight / tilesize_y; y++)
                {
                        for(int x = 0; x < mapwidth / tilesize_x; x++)
                        {
                                int tilepos_x = ((tilemapdata[y][x].index % tilemap_tilewidth) * tilesize_x);
                                int tilepos_y = (tilemapdata[y][x].index / tilemap_tilewidth) * tilesize_y;
                                currenttile.setTextureRect(sf::IntRect(tilepos_x, tilepos_y, tilepos_x + tilesize_x, tilepos_y + tilesize_y));
                                currenttile.setPosition(sf::Vector2f(x * tilesize_x + (tilesize_x / 2), y * tilesize_y + (tilesize_y / 2)));

                                currenttile.setScale(tilemapdata[y][x].flip_x ? -1 : 1, tilemapdata[y][x].flip_y ? -1 : 1); //this line seems to mess things up
                                window.draw(currenttile);
                        }
                }

        window.display();
    }

    return 0;
}
 

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11037
    • View Profile
    • development blog
    • Email
Re: setScale flipping weird graphics
« Reply #1 on: April 25, 2014, 03:12:01 pm »
Since flipping a texture doesn't just create completely different tiles, my guess is that it gets rotated not accord to your expectation, thus it pulls tiles from different parts of the texture.
Did you run a debugger and check if the values match your expectations?

What's the tile texture?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Cervby

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: setScale flipping weird graphics
« Reply #2 on: April 25, 2014, 03:44:37 pm »
Since flipping a texture doesn't just create completely different tiles, my guess is that it gets rotated not accord to your expectation, thus it pulls tiles from different parts of the texture.
Did you run a debugger and check if the values match your expectations?

What's the tile texture?

1. I'm not doing any rotation, just flipping.
2. I included the tile texture in my first post.
3. setScale() shouldn't be able to access any other tile than the one already selected using setTextureRect(), and I know it's setScale() that's causing the problem as it works if I comment that line out and don't flip any tile.

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: setScale flipping weird graphics
« Reply #3 on: April 25, 2014, 06:49:55 pm »
IntRect is made of Left, Top, Width and Height. It was Right and Bottom for the last two in SFML 1.x.
This line is wrong in SFML 2.0:
currenttile.setTextureRect(sf::IntRect(tilepos_x, tilepos_y, tilepos_x + tilesize_x, tilepos_y + tilesize_y));
it should go:
currenttile.setTextureRect(sf::IntRect(tilepos_x, tilepos_y, tilesize_x, tilesize_y));

Because of the order you drew it in when scale was 1, 1 it was looking ok, the 'additional' parts of each tile got overdrawn by later tiles and last row and column drew the 'additional' part outside the window.
That's also why result is so weird with different scale, the tiles rotated around (since texture rect is larger the origin isn't actually in the middle of sprite) and trampled over each other this time...
Very ironic how old SFML Rect class usage, window size, tile drawing order and scale worked together for this 'bug'.
« Last Edit: April 25, 2014, 06:58:21 pm by FRex »
Back to C++ gamedev with SFML in May 2023

Cervby

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: setScale flipping weird graphics
« Reply #4 on: April 25, 2014, 08:19:00 pm »
IntRect is made of Left, Top, Width and Height. It was Right and Bottom for the last two in SFML 1.x.
This line is wrong in SFML 2.0:
currenttile.setTextureRect(sf::IntRect(tilepos_x, tilepos_y, tilepos_x + tilesize_x, tilepos_y + tilesize_y));
it should go:
currenttile.setTextureRect(sf::IntRect(tilepos_x, tilepos_y, tilesize_x, tilesize_y));

Because of the order you drew it in when scale was 1, 1 it was looking ok, the 'additional' parts of each tile got overdrawn by later tiles and last row and column drew the 'additional' part outside the window.
That's also why result is so weird with different scale, the tiles rotated around (since texture rect is larger the origin isn't actually in the middle of sprite) and trampled over each other this time...
Very ironic how old SFML Rect class usage, window size, tile drawing order and scale worked together for this 'bug'.

Thanks, it's working now.