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

Author Topic: image cannot display  (Read 846 times)

0 Members and 1 Guest are viewing this topic.

congwei

  • Newbie
  • *
  • Posts: 2
    • View Profile
image cannot display
« on: November 25, 2023, 05:59:42 pm »
I create a sfml project with cmake on windows, but image cannot display

bye the way, I am a beginner of c++ and sfml, so ignore the style of code, I just want it work.

src/main.cpp
#include "game.hpp"
#include <SFML/Graphics.hpp>

int main() {

    Game game;

    sf::Clock clock;
    sf::Time elapsed;

    float frametime = 1.0f / 60.0f;

    while (game.window.isOpen()) {
        sf::Event event;
        while (game.window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                game.window.close();
            }
        }

        // 1. 事件处理
        game.handleInput();

        // 2. 更新物理逻辑
        if (elapsed.asSeconds() >= frametime) {
            elapsed -= sf::seconds(frametime);
            game.update(); // 60次/秒
        }
        elapsed += clock.restart();

        // 3. 渲染
        game.window.clear();
        game.render();
        game.window.display();
    }

    return 0;
}
 

src/game.hpp
class Game {
  public:
    sf::RenderWindow window;

    sf::Sprite s;

    Game() {
        window.create({320, 480}, "hello");

        sf::Texture t;
        t.loadFromFile("images/tiles.png");

        s.setTexture(t);
    }

    void handleInput() {}

    void update() {}

    void render() { window.draw(s); }
};
 

but if I put draw code into main.cpp, it's work, I dont know why. like this:
src/main.cpp
       ...
        // 3. 渲染
        game.window.clear();
        // game.render();
        sf::Texture t;
        t.loadFromFile("images/tiles.png");

        sf::Sprite s(t);
        game.window.draw(s);
        game.window.display();
       ...
 

« Last Edit: November 25, 2023, 06:11:57 pm by congwei »

congwei

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: image cannot display
« Reply #1 on: November 25, 2023, 06:42:53 pm »
I know the reason, if put sf::Texture t to class member, it work.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: image cannot display
« Reply #2 on: November 25, 2023, 06:56:32 pm »
Hi, welcome, and glad you got it to work! :)

The reason it works as a member of the class is that it continues to exists (as long as the class instance does).

The other two options you mentioned both create a new texture each time and are destroyed at the end of that scope (the closing brace: } )

The one in the class's constructor is destroyed almost immediately.
The one in the loop is destroyed at the end of the loop.

But, the one in the loop is loading the texture every frame and is best avoided. Resources (especially heavy ones like textures) should be loaded once and changed as little as possible.

So, the best option here is, as you've already found, is put the texture as a class member. You can still load it in the constructor but the member lasts as long as the class instance does.

e.g.
class Game {
public:
    sf::Texture t;
    Game() {
        if (!t.loadFromFile("images/tiles.png")) {
            std::cerr << "Unable to load texture!\n";
        }
    }
}

Remember to test the return value (bool) from loadFromFile (as shown in my example) as it informs you if the texture load was successful.
You could throw an exception, for example, as it's likely you wouldn't want to continue without it.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*