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

Author Topic: window.getDefaultView not updated after resize  (Read 2507 times)

0 Members and 1 Guest are viewing this topic.

Ekzee

  • Newbie
  • *
  • Posts: 3
    • View Profile
window.getDefaultView not updated after resize
« on: May 08, 2019, 09:35:03 pm »
Hello!

I'm probably doing something wrong, because I just started learning SFML and graphics, but here is the code to reproduce the issuse:

int main() {
        auto window = sf::RenderWindow(sf::VideoMode(1280, 540), "My window");
        window.setVerticalSyncEnabled(true);
        const float worldWidth = 960;
        const float worldHeight = 540;
        updateView(window, worldWidth, worldHeight, window.getSize().x, window.getSize().y);

        while (window.isOpen()) {

                sf::Event event{};
                while (window.pollEvent(event)) {
                        if (event.type == sf::Event::Closed) {
                                window.close();
                        }
                        if (event.type == sf::Event::Resized) {
                                updateView(window, worldWidth, worldHeight, event.size.width, event.size.height);
                        }
                }

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

                sf::RectangleShape viewArea(sf::Vector2f(worldWidth, worldHeight));
                viewArea.setPosition(0, 0);
                viewArea.setFillColor(sf::Color::Red);
                window.draw(viewArea);

                sf::Vector2i zeroPoint = window.mapCoordsToPixel(sf::Vector2f(0, 0));
                sf::RectangleShape viewAreaStart(sf::Vector2f(50.f, 50.f));
                viewAreaStart.setPosition(sf::Vector2f(zeroPoint.x, zeroPoint.y));
                viewAreaStart.setFillColor(sf::Color::White);

                sf::View view = window.getView();
                window.setView(window.getDefaultView());
                window.draw(viewAreaStart);
                window.setView(view);

                window.display();
        }
        return 0;
}
 

And here is updateView function, which should add spaces on the screen, to keep world aspect ratio:
void updateView(
        sf::RenderTarget& renderTarget,
        const float worldWidth,
        const float worldHeight,
        const float targetWidth,
        const float targetHeight
) {
        float worldAspectRatio = worldWidth / worldHeight;
        float screenAspectRatio = targetWidth / targetHeight;
        sf::FloatRect viewPort = sf::FloatRect(0, 0, 1.f, 1.f);
        if (screenAspectRatio < worldAspectRatio) {
                float widthRatio = targetWidth / worldWidth;
                float scaledWorldHeight = widthRatio * worldHeight;
                float heightDiff = targetHeight - scaledWorldHeight;
                float viewPortHeightOffset = heightDiff / 2 / targetHeight;
                viewPort.top = viewPortHeightOffset;
                viewPort.height = 1.f - viewPortHeightOffset * 2;
        } else {
                float heightRatio = targetHeight / worldHeight;
                float scaledWorldWidth = heightRatio * worldWidth;
                float widthDiff = targetWidth - scaledWorldWidth;
                float viewPortWidthOffset = widthDiff / 2 / targetWidth;
                viewPort.left = viewPortWidthOffset;
                viewPort.width = 1.f - viewPortWidthOffset * 2;
        }
        sf::View view(sf::FloatRect(0.f, 0.f, worldWidth, worldHeight));
        view.setViewport(viewPort);
        renderTarget.setView(view);
}
 

So in the beginning the white ractangle is located at the top left corner of the red rectangle. When I resize the window by adjusting it's width, the white rectangle starts shifting away from the corner, and if im not mistaken, the rectangle should stay in it`s place.

I can "fix" this behaviour by calculating default view myself, like this:
int main() {
        auto window = sf::RenderWindow(sf::VideoMode(1280, 540), "My window");
        sf::View defaultView(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
        const float worldWidth = 960;
        const float worldHeight = 540;
        updateView(window, worldWidth, worldHeight, window.getSize().x, window.getSize().y);
        window.setVerticalSyncEnabled(true);

        while (window.isOpen()) {

                sf::Event event{};
                while (window.pollEvent(event)) {
                        if (event.type == sf::Event::Closed) {
                                window.close();
                        }
                        if (event.type == sf::Event::Resized) {
                                updateView(window, worldWidth, worldHeight, event.size.width, event.size.height);
                                defaultView.setSize(event.size.width, event.size.height);
                                defaultView.setCenter((float) event.size.width / 2, (float) event.size.height / 2);
                        }
                }

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

                sf::RectangleShape viewArea(sf::Vector2f(worldWidth, worldHeight));
                viewArea.setPosition(0, 0);
                viewArea.setFillColor(sf::Color::Red);
                window.draw(viewArea);

                sf::Vector2i zeroPoint = window.mapCoordsToPixel(sf::Vector2f(0, 0));
                sf::RectangleShape viewAreaStart(sf::Vector2f(100, 100));
                viewAreaStart.setPosition(sf::Vector2f(zeroPoint.x, zeroPoint.y));
                viewAreaStart.setFillColor(sf::Color::White);

                sf::View view = window.getView();
                window.setView(defaultView);
                window.draw(viewAreaStart);
                window.setView(view);

                window.display();
        }
        return 0;
}
 

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Back to C++ gamedev with SFML in May 2023

Ekzee

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: window.getDefaultView not updated after resize
« Reply #2 on: May 09, 2019, 06:49:26 am »
Hmmm, isn't it making it kinda useless?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: window.getDefaultView not updated after resize
« Reply #3 on: May 09, 2019, 07:59:35 am »
Please have a look at the documentation and tutorial before making assumptions and asking here ;)

It's not useless. If you build view of size 1000x1000, then you'll see 1000x1000 units of your scene on screen no matter what the size of the window is. If it was adjusted automatically, as you suggest, then it would be useless to give a size to the view in the first place.
Laurent Gomila - SFML developer

Ekzee

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: window.getDefaultView not updated after resize
« Reply #4 on: May 09, 2019, 03:03:04 pm »
Damn, I'm somehow managed to miss the "Showing more when the window is resized" section  :o

Elias Daler

  • Hero Member
  • *****
  • Posts: 599
    • View Profile
    • Blog
    • Email
Re: window.getDefaultView not updated after resize
« Reply #5 on: May 13, 2019, 02:26:52 pm »
This is a thing that confused me a lot recently. Maybe the naming is a bit unfortunate... Because "default" for me meant (0, 0, currentWidth, currentHeight).
If only there was a function which actually returned the view like this.

"default" here is "how SFML will draw it unless you react to resize", right?
Tomb Painter, Re:creation dev (abandoned, doing other things) | edw.is | @EliasDaler