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

Author Topic: Load a white rectangle using Game headerfile  (Read 1176 times)

0 Members and 1 Guest are viewing this topic.

kanbaru

  • Newbie
  • *
  • Posts: 2
    • View Profile
    • Email
Load a white rectangle using Game headerfile
« on: March 16, 2019, 01:31:17 pm »
I followed the book SFML Game Development, and find problem in doing the chapter 2, about resources management.

Here I used:
 
#include "Game.h"
#include <SFML/Graphics.hpp>
void main()
{
        Game game;
        game.run();
}
 
While in the loading function, it turns out rendering a white rectangle.

Game.h
#pragma oncE
#include <SFML/Graphics.hpp>
#include <ResourceHolder.hpp>
#include <iostream>
#include <assert.h>

class Game
{
public:
        Game();
        ~Game();
        void run();
private:
        void processEvents();
        void update(sf::Time deltaTime);
        void render();
        void handlePlayerInput(sf::Keyboard::Key key, bool isPressed);
private:
        sf::Sprite player;
        sf::RenderWindow window;
        sf::Texture playerTexture;
        bool pIsMovingUp= false;
        bool pIsMovingDown = false;
        bool pIsMovingLeft = false;
        bool pIsMovingRight = false;
};
 

Game.cpp
Game::Game()
        : window(sf::VideoMode(800, 600), "Simulator", sf::Style::Default)
        , player()
{
        // window.setFramerateLimit(25);
        //Try to load resources
        ResourceHolder<sf::Texture, Textures::ID> textures;
        try
        {
                textures.load(Textures::MainRole, "Media/textures/a.png");
        }
        catch (std::runtime_error& e)
        {
                std::cout << "Exception: " << e.what() << std::endl;
        }
       
        player.setOrigin(100.0f, 100.0f);
        player.setPosition(400.0f, 300.0f);
        player.setTexture(textures.get(Textures::MainRole));
       
}
 

If I use Game class to run the program, a white rectangle will be the result.
However, when I copy the source code from the book's github, it is OK. And the source code is using main.cpp to run the whole program. Here's the github link.
https://github.com/SFML/SFML-Game-Development-Book/tree/master/02_Resources
« Last Edit: March 16, 2019, 05:02:29 pm by eXpl0it3r »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Load a white rectangle using Game headerfile
« Reply #1 on: March 16, 2019, 05:05:34 pm »
Your ResourceHolder is local to the Game constructor, and is destroyed when it returns.
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10815
    • View Profile
    • development blog
    • Email
Re: Load a white rectangle using Game headerfile
« Reply #2 on: March 16, 2019, 05:09:37 pm »
I hope you're also reading the book and are not just copying code, because I'm pretty sure the book explains why you need a resource holder in the first place.
Once you understand why that is needed, you'd also understand why your code defeats the whole point of it. ;)

You create a resource holder instance that is local to the Game() constructor. So right after the texture is loaded, the resource holder is destroyed again and with it, the texture is destroyed and thus the sprite's reference to the texture is broken and renders a white square.

See also the White Square Problem described in the official tutorial: https://www.sfml-dev.org/tutorials/2.5/graphics-sprite.php#the-white-square-problem

Please make use of the edit function next time, instead of adding a new post every few minutes. :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

kanbaru

  • Newbie
  • *
  • Posts: 2
    • View Profile
    • Email
Re: Load a white rectangle using Game headerfile
« Reply #3 on: March 17, 2019, 03:50:11 am »
Thanks a lot for all the replies.
I am sorry that I post a trivial question, I am new to SFML. Next time, I will pay attention to the format and official document.
I solved this problem by adding static to the ResourceHolder:
static ResourceHolder<sf::Texture, Textures::ID> textures;
Anyway, thanks for your help.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10815
    • View Profile
    • development blog
    • Email
Re: Load a white rectangle using Game headerfile
« Reply #4 on: March 17, 2019, 01:59:59 pm »
It's fine to ask questions, I merely wanted to point out that the code and book sections you're looking at were written to solve this exact issue. Not realizing this, makes it seem like you haven't understood the concept behind and may want to go back to understand it before moving on. ;)

Adding static "solves" the issue, but it would be better if you used the resource holder as class member.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/