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

Author Topic: [Solved] Strange behavior with sf::View  (Read 1418 times)

0 Members and 1 Guest are viewing this topic.

Dr. Cassoulet

  • Newbie
  • *
  • Posts: 2
    • View Profile
[Solved] Strange behavior with sf::View
« on: July 02, 2016, 02:55:44 pm »
Hi everyone !

I work on a little GUI system for fun with SFML and I met a strange behavior with sf::View. I’ve made a simple version of the problem. The goal of this example is to draw 3 rectangles, each one within the other with a viewport.

If i call my function draw like that
draw(window, window.getView());
the last rectangle is not well positioned.
http://imgur.com/91UU5Js

But if I call it like that it works and this confused me a lot…
sf::View myView = window.getView();
draw(window, myView);
http://imgur.com/4kVlLNb

I compared the two views with the Visual Studio debbuger but they are identical.
http://imgur.com/tLVldD1
(even if the hexadecimal number at the beginning of the matrix is different, the content is however identical)

This is the code of the example.

#include <SFML/Graphics.hpp>

void draw(sf::RenderWindow &window, const sf::View &viewWindow)
{
        sf::View viewParent = window.getView();
        //------------------------------------

        //---draw rec1---

        sf::RectangleShape rec1(sf::Vector2f(500, 500));
        rec1.setFillColor(sf::Color::Red);
        rec1.setPosition(360, 110);
        window.draw(rec1);

        sf::View viewRec1(sf::FloatRect(0, 0, rec1.getSize().x, rec1.getSize().y));//create a view with the same size and position as rec1
        viewRec1.setViewport(sf::FloatRect(
                rec1.getPosition().x / viewWindow.getSize().x,
                rec1.getPosition().y / viewWindow.getSize().y,
                rec1.getSize().x / viewWindow.getSize().x,
                rec1.getSize().y / viewWindow.getSize().y
        ));
        window.setView(viewRec1);


        //---draw rec2 inside rec1---

        sf::RectangleShape rec2(sf::Vector2f(300, 300));
        rec2.setFillColor(sf::Color::Green);
        rec2.setPosition(rec1.getSize().x/2 - rec2.getSize().x/2, rec1.getSize().y / 2 - rec2.getSize().y / 2);
        window.draw(rec2);

        sf::View viewRec2(sf::FloatRect(0, 0, rec2.getSize().x, rec2.getSize().y));//create a view with the same size and position as rec2 "inside" the rec1's view
        viewRec2.setViewport(sf::FloatRect(
                window.getView().getViewport().left + (rec2.getPosition().x / viewWindow.getSize().x),
                window.getView().getViewport().top + (rec2.getPosition().y / viewWindow.getSize().y),
                rec2.getSize().x / viewWindow.getSize().x,
                rec2.getSize().y / viewWindow.getSize().y
        ));
        window.setView(viewRec2);


        //---draw rec3 inside rec2

        sf::RectangleShape rec3(sf::Vector2f(100, 100));
        rec3.setFillColor(sf::Color::Blue);
        rec3.setPosition(rec2.getSize().x / 2 - rec3.getSize().x / 2, rec2.getSize().y / 2 - rec3.getSize().y / 2);
        window.draw(rec3);

        //------------------------------------
        window.setView(viewParent);
}


int main()
{
        sf::RenderWindow window(sf::VideoMode(1220, 720), "Test bug view SFML");

        sf::Event event;

        while (window.isOpen())
        {

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

                        else if (event.type == sf::Event::Resized)
                        {
                                window.setView(sf::View(sf::FloatRect(0, 0, event.size.width, event.size.height)));
                        }
                }

                window.clear(sf::Color::White);

                //Don't work, the last rectangle is not center
                //------------------
                //draw(window, window.getView());
                //------------------
               
                //but this work ?!
                //------------------
                sf::View myView = window.getView();
                draw(window, myView);
                //-----------------

                window.display();
        }

        return 0;
}

I’m sure I made a dumb mistake somewhere but I fail to find it. Any ideas ?

Thanks in advance
« Last Edit: July 02, 2016, 06:00:11 pm by Dr. Cassoulet »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Strange behavior with sf::View
« Reply #1 on: July 02, 2016, 05:51:51 pm »
The viewWindow argument of your function is a (const) reference to a view, so if the original view is modified while the function is running, viewWindow will be modified too. When you pass window.getView(), and not a copy of it, this is exactly what happens: when your function calls window.setView(), your viewWindow argument gets modified accordingly, which breaks the logic of the rest of the function.
Laurent Gomila - SFML developer

Dr. Cassoulet

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: [Solved] Strange behavior with sf::View
« Reply #2 on: July 02, 2016, 06:01:46 pm »
Indeed that was really dumb, thank you a lot.  :)