SFML community forums

Help => Graphics => Topic started by: HpHydra on February 04, 2025, 07:02:33 am

Title: Sprite from Drawable object not appearing in window
Post by: HpHydra on February 04, 2025, 07:02:33 am
Hello, I am working on a project using SFML 3.0.0 that involves creating a class that inherits Drawable. The class simply has a Texture and a Sprite with the Texture being loaded from a png file. However, when I create an instance of the class in my main function and draw it in the window loop, nothing appears. I am on MacOs Sequoia (15.2). I've created a minimal example that reproduces my problem so here it is:

MyDrawable.cpp:
Code: [Select]
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <iostream>

class MyDrawable : public sf::Drawable {
public:
    MyDrawable();
    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
private:
    sf::Texture texture;
    sf::Sprite sprite;
};

MyDrawable::MyDrawable() : sprite(texture) {
    if (!texture.loadFromFile("image.png")) {
        std::cerr << "Error loading texture!" << std::endl;
    } else {
        sprite.setTexture(texture);
    }
}

void MyDrawable::draw(sf::RenderTarget& target, sf::RenderStates states) const {
    target.draw(sprite, states);
}

main.cpp:
Code: [Select]
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include "MyDrawable.cpp"

int main() {
    sf::RenderWindow window(sf::VideoMode({800, 800}), "Window");
    MyDrawable drawable;
   
    while (window.isOpen()) {
        while (const std::optional event = window.pollEvent())
        {
            if (event->is<sf::Event::Closed>())
                window.close();
        }

        window.clear(sf::Color::Black);
        window.draw(drawable);
        window.display();
    }

    return 0;
}

Here's some debugging steps I've tried so far:

I've been trying to solve this with no luck, on one hand if the sprite has local bounds of 0x0 that makes me think the sprite is not correctly pointing to my texture. But on the other hand, calling getTexture() on the sprite and saving it to an image file shows the correct png, which makes me think the sprite is pointing to the texture. Any help is greatly appreciated!  ;D
Title: Re: Sprite from Drawable object not appearing in window
Post by: eXpl0it3r on February 04, 2025, 10:47:18 am
The issue is likely that when you set the texture in the initialization list, the texture has no size and thus the texture rect of the sprite will also be set to no size. Then when you load the texture, you never adjust the texture rect and thus nothing is shown.

The sprite.setTexture call isn't necessary, as you've already set the texture by passing it to the sprite, but what you want to do is call sprite.setTextureRect(IntRect({0, 0}, Vector2i(texture.getSize()))) to match the texture size.

MyDrawable::MyDrawable() : sprite(texture) {
    if (!texture.loadFromFile("image.png")) {
        std::cerr << "Error loading texture!" << std::endl;
    } else {
        sprite.setTextureRect(sf::IntRect({0, 0}, sf::Vector2i(texture.getSize())));
    }
}

Or if you're fine with handling exceptions, you could also do:

MyDrawable::MyDrawable() : texture("image.png"), sprite(texture) {
}
Title: Re: Sprite from Drawable object not appearing in window
Post by: Hapax on February 04, 2025, 10:59:59 am
        sprite.setTextureRect(IntRect({0, 0}, Vector2i(texture.getSize())));
 

You can also reset it automatically using:
        sprite.setTexture(texture, true); // note the added "true" here
 

but internally it just does the code that eXpl0it3r posted anyway and doing that manually gives more control in case you might want to use a part of the texture instead of the entire image.

In fact, if you use eXpl0it3r's code, you'll likely need to add "sf::" to the IntRect and the Vector2i ;)



On a separate note, there is no longer any need to use "virtual" keyword when you provide an "override" keyword.
Title: Re: Sprite from Drawable object not appearing in window
Post by: eXpl0it3r on February 04, 2025, 12:45:30 pm
In fact, if you use eXpl0it3r's code, you'll likely need to add "sf::" to the IntRect and the Vector2i ;)
That's what I get for copy-pasting ;D
It's fixed ;)
Title: Re: Sprite from Drawable object not appearing in window
Post by: HpHydra on February 04, 2025, 05:14:54 pm
Thank you both for your help, Problem solved!

P.S. slightly embarrassing that I somehow missed the resetRect parameter on setTexture, ah well, thanks again! :D