Search code examples
c++sfml

Why the texture appears only in the first quadrant


What's wrong with this code using SFML?

In the code below, I have this image (1000x1000) and I want to show it in a window (500x500) using sf::RenderTexture. However, only part of the image appears in the first quadrant:

#include <SFML/Graphics.hpp>
using namespace sf;

int main()
{
    RenderWindow window({500, 500}, "SFML Views", Style::Close);

    View camera;
    camera.setSize(Vector2f(window.getSize()));

    Texture background;
    background.loadFromFile("numeros.png");
    Sprite numeros (background);

    RenderTexture texture;
    texture.create(window.getSize().x, window.getSize().y);

    Sprite content;
    content.setTexture(texture.getTexture());

    texture.draw(numeros);
    texture.display();

    while (window.isOpen())
    {
        for (Event event; window.pollEvent(event);)
            if (event.type == Event::Closed)
                window.close();
        window.clear();
        window.setView(camera);
        window.draw(content);
        window.display();
    }
    return EXIT_SUCCESS;
}

enter image description here

As far as I can understand, the code should generate the original image (1000x1000) automatically adjusted to 500x500.

Could anyone tell you what is wrong?


Solution

  • You're facing, in fact, two distinct problems:

    First one:

    As far as I can understand, the code should generate the original image (1000x1000) automatically adjusted to 500x500.

    This is not really true. SFML handles the sprites with the real size of the texture. If your image is 1000x1000, but you want representing it as 500x500, you should assign the texture to a sprite, as you do:

    Sprite numeros(background);

    and then scale this sprite to fit in a 500x500 window, this is:

    numeros.setScale(0.5, 0.5);

    With this change you should view the whole image, but...

    Second one:

    You're messing with the view of the window. If we check SFML documentation, we can see that sf::View expects:

    • A sf::FloatRect: this is, a coordinate (x,y) - in this case the top-left corner - and a size(width, height)

    or

    • Two sf::Vector2f: one corresponding to the coordinates of the center and the other corresponding to the size of the view.

    Assuming you want to use the second one, you're missing the first parameter, the center coordinates, but this is not really necessary. If you simply don't apply the view, the image should be shown in the whole window.

    So you simply need to remove:

    window.setView(camera);


    The code I've tried:

    int main()
    {
        RenderWindow window({ 500, 500 }, "SFML Views", Style::Close);
    
        View camera;
        camera.setSize(Vector2f(window.getSize()));
    
        Texture background;
        background.loadFromFile("numeros.png");
        Sprite numeros(background);
        numeros.setScale(0.5, 0.5);   // <-- Add this
    
        RenderTexture texture;
        texture.create(window.getSize().x, window.getSize().y);
    
        Sprite content;
        content.setTexture(texture.getTexture());
    
        texture.draw(numeros);
        texture.display();
    
        while (window.isOpen())
        {
            for (Event event; window.pollEvent(event);)
            if (event.type == Event::Closed)
                window.close();
            window.clear();
            //window.setView(camera);    <-- Remove this
            window.draw(content);
            window.display();
        }
        return EXIT_SUCCESS;
    }
    

    And my result:

    enter image description here