SFML community forums

Help => Graphics => Topic started by: Missqu on March 03, 2025, 06:35:48 am

Title: Graphical glitch appearing
Post by: Missqu on March 03, 2025, 06:35:48 am
Hello, I experience graphical glitch. I attached 2 screenshots, 1 with and 1 without graphical bug.
minimal code looks something like so
Quote

#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
sf::Texture default_texture("my default texture.png");
struct Sprite
{
    explicit Sprite() {}
    explicit Sprite(const sf::Texture& _texture) : sprite_(_texture) {}
    std::optional<sf::Sprite> sprite_ = std::nullopt;
};
Sprite first_sprite;
std::vector<Sprite> sprites;

  void init()
      {
        first_sprite.sprite_->setTexture(default_texture);
        for (int i =0; i < 5;++i)
        {
          sprites.push_back(first_sprite);
        }
    }
int main()
{
    //init

    sf::RenderWindow window(sf::VideoMode({800, 600}), "SFML window");
    init();
    while (window.isOpen())
    {
        while (const std::optional event = window.pollEvent())
        {
            // Close window: exit
            if (event->is<sf::Event::Closed>())
                window.close();
        }
        window.clear();
        for (int i =0; i < sprites.size(); ++i)
        {
          if (sprites.sprite_.has_value())
          {
            window.draw(sprites.sprite_.value());
          }
        }
        window.display();
    }
}
Whether or not the glitch appears I seem to be able to reliable reproduce based on the size of vector of sprites. (For examples I push_back 5 Sprites it appears, I do 7 it doesn't.
 
The wrapper for sf::Sprite is necessary I can't go around it.
OS: archlinux
Why is this happening? What might be the cause? I am at loss here, I seem to be lacking some knowledge. Might be because I copy the sprite, but I had no issue in the past.
Title: Re: Graphical glitch appearing
Post by: eXpl0it3r on March 03, 2025, 08:44:08 am
Looks like your second screenshot didn't make it. ;D

You shouldn't be using SFML resources at a global scope. This can and eventually will lead to problems with global initialization or destruction order. Generally, the use of globals are not recommended.

When you push_back the sprite, you create a copy of it. Make sure that your struct will correctly copy its members as well.
Title: Re: Graphical glitch appearing
Post by: Missqu on March 03, 2025, 11:00:46 pm
I made a mistake, I actually store sf::Texture in class as unordered map, like so:
Quote
class ResourceManager
{
public:
    ResourceManager();



    sf::Texture* load(std::string _path);
    sf::Texture* get(std::string _path);

private:
    std::unordered_map<std::string, std::unique_ptr<sf::Texture>> textures_;
};
sf::Texture* ResourceManager::load(std::string _path)
{
   sf::Texture texture_temp;
   if (!texture_temp.loadFromFile(_path))
   {
      std::cerr << "Error loading texture " << _path << std::endl;
      return nullptr;
   }

      textures_[_path] = std::make_unique<sf::Texture>(_path);

   return textures_[_path].get();
}

sf::Texture* ResourceManager::get(std::string _path)
{
   return textures_[_path].get();
}
I also attached second screenshot. My bad should have double checked things.
Title: Re: Graphical glitch appearing
Post by: Hapax on March 03, 2025, 11:53:08 pm
If you want to avoid the copying (mentioned above by eXpl0it3r), you could skip the "first sprite" temp and construct it directly in the vector since you already have a constructor ready:
sprites.emplace_back(default_texture);
Title: Re: Graphical glitch appearing
Post by: eXpl0it3r on March 04, 2025, 02:42:21 pm
It's hard to say if the presented code isn't want you're actually using and it's unclear if it would even reproduce the issue.

The behavior here sounds similar to the white square problem, but that usually arises when using textures in a std::vector.
It's important to realize that std::vector will automatically relocate all its items from one memory location to another memory location when adding new items. So what you're likely notice is that between 5 and 7 elements, the vector moves all the items to a new memory location and thus breaks some references/pointers.

As a test, you could reserve() the right amount elements, thus pre-allocating enough space and guaranteeing that the items don't need to be moved. Alternatively, you might consider a stable container or a std::unique_ptr.

    std::unordered_map<std::string, std::unique_ptr<sf::Texture>> textures_;

    // ...

    textures_[_path] = std::make_unique<sf::Texture>(_path);
 
std::unordered_map is already a stable container and you don't really need a unique_ptr here, if you're going to return raw pointers anyways.
You can then just emplace the texture: textures_.emplace(_path, _path)
Title: Re: Graphical glitch appearing
Post by: Missqu on March 31, 2025, 12:33:06 am
Allright, I am sorry for late response.
I am not exactly sure what happened, but I copied my up to date code. Rollbacked project few weeks the issue disappeared... Applied updated code, still couldn't reproduce the bug.
So yeah, it seems like there was something gnarly going on with project tree most likely, I have no idea what, maybe some stray include(that is my educated guess).