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

Author Topic: Make image fill either vertical or horizontal space while keeping aspect ratio.  (Read 3847 times)

0 Members and 1 Guest are viewing this topic.

Zaper127

  • Newbie
  • *
  • Posts: 3
    • View Profile
So I'm new to c++ and SMFL. I'm trying to set a background image and have it fill the window as much as possible to, filling either top to bottom or left to right depending on the image and window dimensions. I have tried that letter boxing wiki that shows up in all the searches, and serval other things.

With the View/letter boxing the image centers but doesn't scale. with my attempts I can get it to fill the width but won't maintain aspect ratio. Here are to two codes I've tried:

//Letterbox code always referred to on these forms
                sf::View getLetterboxView(sf::View view, sf::Vector2u windowSize) {
               
                // Compares the aspect ratio of the window to the aspect ratio of the view,
                // and sets the view's viewport accordingly in order to archieve a letterbox effect.
                // A new view (with a new viewport set) is returned.

                float windowRatio = (float)windowSize.x / windowSize.y;
                float viewRatio = (float)view.getSize().x / view.getSize().y;
                float sizeX = 1;
                float sizeY = 1;
                float posX = 0;
                float posY = 0;

                bool horizontalSpacing = true;
                if (windowRatio < viewRatio) horizontalSpacing = false;

                // If horizontalSpacing is true, the black bars will appear on the left and right side.
                // Otherwise, the black bars will appear on the top and bottom.

                if (horizontalSpacing) {
                        sizeX = viewRatio / windowRatio;
                        posX = (1 - sizeX) / 2.f;
                }
                else {
                        sizeY = windowRatio / viewRatio;
                        posY = (1 - sizeY) / 2.f;
                }

                view.setViewport(sf::FloatRect(posX, posY, sizeX, sizeY));

                return view;
        }
//My own attempts
        sf::Sprite setBackground(sf::Vector2u windowSize, sf::Texture& background) //preps image background
        {

                sf::Sprite backgroundSprite;
                backgroundSprite.setTexture(background);
                float scale;

                //I have tried several formula attempts, this is just my last attempt
                if (windowSize.x >= windowSize.y) scale= (float)windowSize.x / background.getSize().x;
                else  scale = (float)windowSize.y / background.getSize().y;
                backgroundSprite.setScale(scale, scale);

                return backgroundSprite;
        }


And this is how I call the functions:
   
bool mouseleftpressed;
                sf::Vector2u windowSize(window.getSize());
                //Background
                        sf::Texture background = setTexture("images/backgrounds/Grassy_Mountains_preview_fullcolor.png");
                        sf::Sprite backgroundImage = setBackground(windowSize, background);
                        sf::View backgroundView;

                        backgroundView.setSize(windowSize.x, windowSize.y);
                        backgroundView.setCenter(backgroundView.getSize().x / 2, backgroundView.getSize().y / 2);
                        backgroundView = getLetterboxView(backgroundView, windowSize);
                //
                                while (window.pollEvent(event))
                                {
                                        if (event.type == sf::Event::Closed) { mode = 3; };

                                        if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
                                        {
                                                mouseleftpressed = 1;
                                        }
                                        if (sf::Event::MouseButtonReleased && (mouseleftpressed == 1))
                                        {
                                                sf::Vector2i clickedco = sf::Mouse::getPosition(window);
                                                mouseleftpressed = 0;
                                        }
                                        if (event.type == sf::Event::Resized)
                                        {
                                                windowSize.x = event.size.width;
                                                windowSize.y = event.size.height;
                                                sf::Sprite backgroundImage = setBackground(windowSize, background);
                                        }
                                }

You guys have any ideas or a good tutorial link? Please remember I am a beginner in C++ and SFML.

Zaper127

  • Newbie
  • *
  • Posts: 3
    • View Profile
Alright. I figured it out, the issue is I was using the view incorrectly. I can’t explain exactly what i was doing but prt of it was setting the scale of the sprite within the view.