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

Author Topic: [Solved] Change viewport to keep aspect ratio of scene  (Read 21151 times)

0 Members and 1 Guest are viewing this topic.

Gobbles

  • Full Member
  • ***
  • Posts: 132
    • View Profile
    • Email
Re: Change viewport to keep aspect ratio of scene
« Reply #15 on: August 01, 2014, 05:44:30 am »
I must've misread your question, but what this does for me is as I alter one dimension of the screen, the other dimension adjusts to maintain a 4:3 aspect Ratio. Coupled with a sf::Style::Resize in the window, this allows me to drag the window to whatever size I'm most comfortable with. What exactly are you looking for?

JoshuaBehrens

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Change viewport to keep aspect ratio of scene
« Reply #16 on: August 01, 2014, 07:14:00 am »
I want to always see the whole scene so if my scene has an aspect ratio of 1:1 and the width is greater than the height of the window I need black panels on the upper and lower part of the window (vice versa for height > width). And I try to achieve this with using glViewport as used with the viewport from sf::View.

maly

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Change viewport to keep aspect ratio of scene
« Reply #17 on: August 01, 2014, 08:42:49 am »
when you resize the window always set a new view.

basicSettings.screenx and basicSettings.screeny doing strange offsets.
sf::View v( sf::FloatRect( sf::Vector2f( basicSettings.screenx, basicSettings.screeny ), \
                               sf::Vector2f( basicSettings.screenw, basicSettings.screenh ) ) );
try
sf::View v( sf::FloatRect( sf::Vector2f( 0, 0 ), \
                               sf::Vector2f( basicSettings.screenw, basicSettings.screenh ) ) );

example
#include <SFML/Graphics.hpp>

sf::View calcView(const sf::Vector2u &windowsize, const sf::Vector2u &designedsize)
{
    sf::FloatRect viewport(0.f, 0.f, 1.f, 1.f);

    float screenwidth = windowsize.x / static_cast<float>(designedsize.x);
    float screenheight = windowsize.y / static_cast<float>(designedsize.y);

    if(screenwidth > screenheight)
    {
        viewport.width = screenheight / screenwidth;
        viewport.left = (1.f - viewport.width) / 2.f;
    }
    else if(screenwidth < screenheight)
    {
        viewport.height = screenwidth / screenheight;
        viewport.top = (1.f - viewport.height) / 2.f;
    }

    sf::View view( sf::FloatRect( 0, 0, designedsize.x , designedsize.y ) );
    view.setViewport(viewport);

    return view;
}

int main()
{
    const sf::Vector2u designedsize(320,200);

    sf::RenderWindow app(sf::VideoMode(800, 400), "SFML window");
    app.setView(calcView(app.getSize(), designedsize));

    while (app.isOpen())
    {
        sf::Event event;
        while (app.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                app.close();
            if (event.type == sf::Event::Resized)
                app.setView(calcView(sf::Vector2u(event.size.width, event.size.height), designedsize));
        }

        app.clear();
        sf::CircleShape circle(5);
        for(int y = 0; y < designedsize.y/10; ++y)
        {
            for(int x = 0; x < designedsize.x/10; ++x)
            {
                circle.setPosition(x * 10, y * 10);
                circle.setFillColor( (x + y) & 1 ? sf::Color::Blue:sf::Color::Green);
                app.draw(circle);
            }
        }
        app.display();
    }
    return 0;
}

kimci86

  • Full Member
  • ***
  • Posts: 123
    • View Profile
Re: Change viewport to keep aspect ratio of scene
« Reply #18 on: August 01, 2014, 10:45:01 am »
Here is how I would do it.
I hope it helps.

sf::View calcView(const sf::Vector2f& windowSize, float minRatio, float maxRatio)
{
    sf::Vector2f viewSize = windowSize;

    // clip ratio
    float ratio = viewSize.x / viewSize.y;
    if(ratio < minRatio) // too high
        viewSize.y = viewSize.x / minRatio;
    else if(ratio > maxRatio) // too wide
        viewSize.x = viewSize.y * maxRatio;

    sf::View view(sf::FloatRect(sf::Vector2f(), viewSize));

    sf::FloatRect viewport((windowSize - viewSize) / 2.f, viewSize);
    viewport.left /= windowSize.x;
    viewport.top /= windowSize.y;
    viewport.width /= windowSize.x;
    viewport.height /= windowSize.y;
    view.setViewport(viewport);

    return view;
}

Hapax

  • Hero Member
  • *****
  • Posts: 3346
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Change viewport to keep aspect ratio of scene
« Reply #19 on: August 01, 2014, 11:23:26 pm »
Well percentages and ratios both are usually used with values between 0..1 and as I am not a native English speaker I might tend to use wrong words.
For your information, percentage is usually in the range of 0 to 100.

I convert from pixel to ratio with this:
    viewport.width  = viewport.width  / W.x;
    viewport.height = viewport.height / W.y;
And all before this is pixel and all after this is in ratio units.
You store pixel width and ratio width in the same variable - viewport.width? I see that now but it's not very clear or logical.

Can't you write something more helpful? If you already had the same problem why can't you give a hint, where I should rethink my code or give (pseudo-)code.
A lot of code has been given by others since this but I'm still not 100 percent sure what your aim is.
I know that you want letterboxing when the window is no longer the same ratio.
I don't think you've specified whether or not you want the actual letterboxed display to stay the original size or stretch to fit the window. If stretched, the view can stay almost the same (which was why I mentioned it in my first post). If not, the view is the identical to the window and the viewport is the only thing that changes.

If you still haven't solved it from others' code, and you've explained what your aim is, let me know and I'll look into it for you (it's been a while since I worked with this so I don't have the answer at hand).
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

JoshuaBehrens

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Change viewport to keep aspect ratio of scene
« Reply #20 on: August 02, 2014, 01:19:22 am »
@Hapax: Well then I know why we miscommunicate as you see percentage in a range of 0..100(which is absolutely right) and I just called it percentage as it should not be larger than 100% = 1.0.
I can understand your misinterpretation of the doubled usage of the floatrects properties width/height on the one hand in pixels and on the one hand in ratios.
The code from the others works, but I found an other error(continue reading).

@mely: I just tested your example and it worked perfectly. I put it into my application and it was working. Then I changed the code from relying on window.getSize( ) on my variables windoww and windowh. Then it was not working and stretching wrong. Then I found a typo in my resize-event where I asign the new width and height to windoww but windowh is not affected. So I guess even my code should have worked without the typo (not tested).

Thank you for your patience and pointing me (unintentionally) to an error (I should have been aware of).