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

Author Topic: Scaling no-repeat-textured full-window rectangle on resize  (Read 327 times)

0 Members and 1 Guest are viewing this topic.

meta_leap

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Scaling no-repeat-textured full-window rectangle on resize
« on: December 08, 2023, 04:49:31 pm »
Using 2.6.1. With this init code:

    myTex.loadFromFile("mypic.jpg");
    myRect.setTexture(&myTex);

consider this update/render loop:


    void onRender(sf::RenderWindow &window) {
        const auto size_tex = myTex.getSize();
        const auto size_window = window.getSize();

        myRect.setTextureRect({0, 0, (int)size_tex.x, (int)size_tex.y});
        myRect.setSize({(float)size_window.x, (float)size_window.y});

        window.draw(myRect);
    }


Initially the code creates the unbordered window at 1920x1080 on a 3840x2160 screen. There, all the 4 texture corners are in the 4 rect corners and thus the 4 window corners.

The problem: "maximizing" it (fullscreen since window is borderless with no decorations/titlebars etc), the window/screen-as-a-whole only shows exactly the top-left quarter of the texture. (Same when I explicitly set myRect's position and origin to 0,0 every time.)

What might I be missing here?
« Last Edit: December 09, 2023, 11:53:28 am by meta_leap »

Hapax

  • Hero Member
  • *****
  • Posts: 3370
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Scaling no-repeat-textured full-window rectangle on resize
« Reply #1 on: December 10, 2023, 08:33:05 pm »
Views.

These are hard to get hold of at first so don't be disheartened!

A view tells SFML (and OpenGL) which rectangle should fill the window.
Every SFML render window has (and needs) a view but you can change it whenever you like.

When your 1920x1080 window is created, the window also creates a 1920x1080 view. This means that everything from (0, 0) to (1920, 1080) will be in the window and fill the entire window.

When you change the size of the window (we'll presume a 3840x2160 window for simplicity but it may not be exactly that depending on other parts of the display), the view doesn't (automatically) change. This means that the view is still 1920x1080 and will fill the window with (0, 0) to (1920, 1080)! So, when you then resize the rectangle past that range, you're displaying outside of the window!

When you get the size of the window, you are getting the actual size of the window. However, what you actually want (in this case) is the size of the view. You can do that like this (instead of window.getSize()):
const auto size_view = window.getView().getSize();
Note that this is a size using floats so you would no longer need to cast.
i.e.:
myRect.setSize(size_view);

In the tutorial about views, here:
https://www.sfml-dev.org/tutorials/2.6/graphics-view.php
there is a section near the end that describes updating the view to match the window, here:
https://www.sfml-dev.org/tutorials/2.6/graphics-view.php#showing-more-when-the-window-is-resized

This would change the view to match the window so the view was now 3840x2160 (and your increased rectangle size would fit perfectly). Note, though, that it's still the view that matters so getting the view size (instead of the window size) is a better choice.

You can also store one or more views and manipulate them directly. Then, you can set the window's view to which view you choose when you draw. This allows certain drawable objects to be drawn using different views, which allows for things like UI overlap etc.. Note that view have nothing to do with layers; they only affect the co-ordinates used (apart from viewports).



Just for a example of how a view works, you could also choose to have a view that goes from (0, 0) to just (1, 1) and that means that a position of (0.5, 0.5) would be right in the centre of the window! This decouples the drawing co-ordinates from the pixel size of the window.

In fact, the way you describe a view is by giving a size and its centre (not top-left) so you always know the co-ordinate that is in the centre of the window (e.g. window.getView().getCenter())

Viewports complicate things but, basically, you can place that view co-ordinate system in a specific rectangle within the window (and it'll clip anything outside of it). You probably don't need to know that though - at least, not yet! - but it's worth knowing they exist.



There is a more in-depth tutorial on views in the SFML wiki (written by a member of the SFML team) and explains better how they work and how you can use them:
https://github.com/SFML/SFML/wiki/Tutorial%3A-Using-View
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

meta_leap

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: Scaling no-repeat-textured full-window rectangle on resize
« Reply #2 on: December 11, 2023, 02:51:00 pm »
Wow, thanks for this rich wealth of detail and of course also the solution to acute issue  =)  I'll follow these reads, merci!