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

Author Topic: Issue with a Y offset on viewport  (Read 860 times)

0 Members and 1 Guest are viewing this topic.

runyonave

  • Newbie
  • *
  • Posts: 3
    • View Profile
Issue with a Y offset on viewport
« on: November 01, 2022, 03:41:03 am »
I am trying to do something really basic with sf::View.

On a 1280x720 pixel window, I need to place a viewport which is 560x560 with a 160px gap from the top.

What I get is this:

https://imgur.com/a/2zhiV7S

It creates the correct gap length, but it also applies a gap at the bottom

Code I wrote for the viewport:

    int viewport_bl_OffsetX = 0;
    int viewport_bl_OffsetY = 160;
    int viewport_bl_W = 560;
    int viewport_bl_H = 560;

    sf::View viewBL(sf::FloatRect(
        static_cast<float>(viewport_bl_OffsetX),
        static_cast<float>(viewport_bl_OffsetY),
        static_cast<float>(viewport_bl_W),
        static_cast<float>(viewport_bl_H)
    ));

    float viewport_bl_OffsetXRatio = static_cast<float>(viewport_bl_OffsetX) / window_W;
    float viewport_bl_OffsetYRatio = static_cast<float>(viewport_bl_OffsetY) / window_H;

    float viewport_bl_WRatio = static_cast<float>(viewport_bl_W) / window_W;
    float viewport_bl_HRatio = static_cast<float>(viewport_bl_H) / window_H;

    viewBL.setViewport(sf::FloatRect(
        viewport_bl_OffsetXRatio, // 0.00000000
        viewport_bl_OffsetYRatio, // 0.222222224
        viewport_bl_WRatio, // 0.437500000
        viewport_bl_HRatio // 0.777777791
    ));
 

The ratios seem to be correct, but I am not sure why it leaves a gap at the bottom.
« Last Edit: November 01, 2022, 04:00:33 am by runyonave »

kojack

  • Sr. Member
  • ****
  • Posts: 314
  • C++/C# game dev teacher.
    • View Profile
Re: Issue with a Y offset on viewport
« Reply #1 on: November 01, 2022, 01:08:54 pm »
What I believe is happening here (after some experimenting) is your viewport is being set correctly to be from 0,160 to 560,720 (so its a 560x560 region in the bottom left).
The view is being scaled so the coordinates 560x560 match the viewport (the viewport is based on window size, the view is the coordinates inside of the viewport).

But the y offset is being applied to both view and viewport. If the view y offset was 0, then the top left of the inside of the viewport is mapped to 0,0 and the bottom right to 560,560. If the view y offset is set to 160, then the top left of the viewport is mapped to 0,160 and the bottom right to 560,720. So if you then draw stuff assuming 560 is the bottom edge, it will stop at the window's 560 instead of 720.

For example, here I've got a 1280x720 window and a 560x560 sprite. I'm using your settings (view is 0,160,560,560. viewport is 0,0.2222,1,0.4375,0.7777).
The blue and white grid part is the actual area of the viewport. The sprite is starting too high, so it doesn't go all the way to the bottom and you can see some of the blue area that should be covered up.

Here is everything the same, but I set the view's y position to 0.
« Last Edit: November 04, 2022, 08:18:30 am by kojack »

runyonave

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Issue with a Y offset on viewport
« Reply #2 on: November 01, 2022, 05:48:06 pm »
Thanks for looking in to this Kojak. I think I understand what the issue would be with the Y position of the quad placement. I am just not sure what you mean by setting the view's Y position. Are you reseting the view position after the viewport has been set?

I have found that setting the center to half of the width and height sets the image in the correct position.

E,g, viewBL.setCenter(sf::Vector2f(280.f, 280.f));

I have attached a screenshot with how it looks now.


kojack

  • Sr. Member
  • ****
  • Posts: 314
  • C++/C# game dev teacher.
    • View Profile
Re: Issue with a Y offset on viewport
« Reply #3 on: November 01, 2022, 06:31:03 pm »
I am just not sure what you mean by setting the view's Y position. Are you reseting the view position after the viewport has been set?

Here's the code I used:
                        static float vw = 560; // view width
                        static float vh = 560; // view height
                        static float vpw = 560.0; // viewport width
                        static float vph = 560.0; // viewport height
                        static float vpy = 160.0; // viewport y offset

                        sf::FloatRect vp(sf::Vector2f(0.0f, vpy / 720.0), sf::Vector2f(vpw / 1280.0, vph / 720.0));
                        sf::View v(sf::FloatRect(sf::Vector2f(0, 0),sf::Vector2f((float)vw, (float)vh)));
                        v.setViewport(vp);
                        g_window.setView(v);
 
There was ImGui stuff in the middle (to let me adjust it at run time), which is why I had static variables there.

So the viewport values define where it is in the window and how big it is, using values of 0-1.
The view then defines how the rendering coordinates are stretched into the viewport.

I've been using SFML for many years, I still had to write a test program to make sure I understood what was going on before posting. It's a bit confusing. :)
(Actually I'd never used a viewport. Views all the time, never a viewport that I can remember).

runyonave

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Issue with a Y offset on viewport
« Reply #4 on: November 01, 2022, 07:28:13 pm »
Wow, thank you! This makes a lot more sense. Plus it's a much simpler way of setting the viewport than what I was doing.