1

I am having a difficulty in SFML 2.1

I have a class which has inherited SF Drawable and SF Transformable. This class has two sprites. Both the sprites position are relative to the class object's position.

Now is it possible to make the first sprites's size relative to the class object's size while keeping the second sprite's size still constant? Problem is the moment I change the object's size, both the sprites change their size accordingly (as they should), but I don't want the second sprite to change its size. Is there any way to do it, perhaps by altering the transform matrix?

DarkNemesis
  • 109
  • 1
  • 11
  • I don't have a full answer, but I can provide the general steps I would try to follow. 1) Render first sprite as usual. 2) Push the transform matrix. 3) Calculate a "scale" for x and y based on the existing transform matrix (I don't know how/if this is possible; it probably doesn't have a solution for all 4x4 matrices but does for the ones you care about). 4) Calculate a scale matrix using the inverse of the scale just found. 5) Multiply onto existing matrix. 6) Render second sprite. 7) Pop matrix. – J Trana Sep 13 '14 at 03:54
  • Looks like [this](http://stackoverflow.com/questions/16359246/how-to-extract-position-rotation-and-scale-from-matrix-svg) talks about extracting, amongst other things, scale for x and y. Good luck! – J Trana Sep 13 '14 at 03:57
  • @JTrana With SFML we have [`sf::Transform`](http://sfml-dev.org/documentation/2.1/classsf_1_1Transform.php) to manipulate matrixes with rendering state so we don't have to pop/push matrixes by hand. – Hiura Sep 13 '14 at 08:39

1 Answers1

1

Since you inherit from sf::Transformable and sf::Drawable, you can override the draw function and apply a custom transform to one sprite and another transform to the other. For example:

#include <SFML/Graphics.hpp>

class X : public sf::Drawable, public sf::Transformable {
    sf::Sprite s1, s2;
    sf::Texture t;
public:

    X() {
        sf::Image img; img.create(20, 20, sf::Color::Blue);
        t.loadFromImage(img);
        s1.setTexture(t);
        s2.setTexture(t);
        s2.setPosition(50, 50);
    }

    void draw(sf::RenderTarget& target, sf::RenderStates states) const override {
        auto originalStates = states; // save for later 'reset'

        auto transform = getTransform();
        auto scale = getScale();
        transform.scale(1.f/scale.x, 1.f/scale.y); // unscale
        states.transform *= transform;
        target.draw(s1, states);

        states = originalStates;
        states.transform *= getTransform();
        target.draw(s2, states);
    }
};


int main(int, char const**)
{
    // Create the main window
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");

    X x;

    // Start the game loop
    while (window.isOpen())
    {
        // Process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            // Close window : exit
            if (event.type == sf::Event::Closed) {
                window.close();
            }

            if (event.type == sf::Event::KeyPressed) {
                if (event.key.code == sf::Keyboard::Up) {
                    x.scale(1.05, 1.05);
                } else if (event.key.code == sf::Keyboard::Down) {
                    x.scale(0.95, 0.95);
                } else if (event.key.code == sf::Keyboard::Right) {
                    x.move(10, 0);
                } else if (event.key.code == sf::Keyboard::Left) {
                    x.move(-10, 0);
                }
            }
        }

        window.clear();
        window.draw(x);
        window.display();
    }

    return EXIT_SUCCESS;
}
Hiura
  • 3,500
  • 2
  • 20
  • 39
  • Thanks, it worked. I had another doubt, we generally have 3x3 transformation matrices for the three dimensions, but why does SFML has 4? – DarkNemesis Sep 13 '14 at 14:11
  • It's because OpenGL use 4x4 matrices. [Overmind's answer](https://www.opengl.org/discussion_boards/showthread.php/159690-why-4x4-matrix?p=1135708&viewfull=1#post1135708) gives you a quick explanation. – Hiura Sep 13 '14 at 17:06