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

Author Topic: Very weird sprite behaviour (white rectangle when attempting to draw sprite)  (Read 2595 times)

0 Members and 1 Guest are viewing this topic.

Beagle

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Hey everyone :)

So, I've come across a very weird type of behaviour that has left me stumped.

First of all, I have successfully managed to draw a rain cloud picture using this code:

main.cpp
int main()
{
        RenderWindow window(VideoMode(800, 500), "Rain Cloud");

        WorldEntity rainCloud = WorldEntity();

        while (window.isOpen())
        {
                Event event;

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

                window.clear();
                window.draw(rainCloud.getSprite());
                window.display();
        }

        return 0;
}

And here's my simple WorldEntity class:
/*
WorldEntity is a collection of basic properties needed by all objects that needs to exist within the game world
*/

class WorldEntity
{
private:
        Sprite m_sprite;
        Vector2f m_position;
        Texture mahTexture;
public:
        WorldEntity::WorldEntity()
        {
                mahTexture.loadFromFile("RainCloud.png");
                m_sprite = Sprite(mahTexture);
                m_position = Vector2f(0, 0);
        }

        void setPosition(float x, float y);
        void setPosition(Vector2f newPosition);
        Sprite getSprite();
};

#endif

Now, this code works perfectly and the rain cloud sprite is drawn. However... if I do the following change to the WorldEntity class:
        WorldEntity::WorldEntity(Texture test)
        {
                mahTexture.loadFromFile("RainCloud.png");
                m_sprite = Sprite(mahTexture);
                m_position = Vector2f(0, 0);
        }

That is, I now pass a texture called "test" by value (Notice I do NOT use it for anything at all!). And then change the first part of the main.cpp source code to pass a texture instead:
        Texture texture_rainCloud;
       
        if (!texture_rainCloud.loadFromFile("TheActual.png"))
                cout << "Dummy textureTexture failed to load" << endl;

        WorldEntity rainCloud = WorldEntity(texture_rainCloud);

It does not work anymore. That is, now I get a white rectangle drawn instead of the cloud! Notice that all I did was simply pass a texture into the WorldEntity class that I do not even use for anything at all. I changed literally nothing but the fact that a texture is now passed to the constructor, and I don't use that variable for anything.

What exactly is going on there!? :D Anyone has any ideas?
« Last Edit: June 15, 2014, 07:32:15 pm by Beagle »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
In the original version, you got lucky and the compiler optimized away the copy of WorldEntity, meaning it got constructed in place and as such the address of the texture the sprite refers to did not change after you set it.

In the second version, you weren't so lucky and the compiler didn't optimize away the copy resulting in the whole WorldEntity being member-wise copied after you set the texture of the sprite. Copying the sprite consists of a member-wise copy as well, including copying the address of the texture in the temporary WorldEntity. When the temporary gets destroyed, the texture in it gets destroyed as well, and the address of the texture that the sprite refers to becomes invalid leading to the infamous white square.

Don't copy when you don't need to. Use more references. Or just enable C++11 and go for moves.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Beagle

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Hey Binary1248!

Thank you so much for the reply :) I'm quite new to C++ but attempting to learn by simply throwing myself out in a project. Thank you, I did not realize that the syntax I used actually caused any copying! So what you are saying is that when you use syntax such as:

WorldEntity rainCloud = WorldEntity(...)

It will actually construct a worldEntity object and then copy it to the "rainCloud" variable due to the assignment operator? So if I instead use:
WorldEntity rainCloud(...)

Then I construct it "in place" for the rainCloud object? Which will not cause any copying.

Thank you for your time!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Yes -- however, compilers are allowed to optimize this copy away.

Still, there's no need to name the type twice in a declaration.
WorldEntity rainCloud;      // default constructor
WorldEntity rainCloud(...); // parameter constructor

As a general advice, don't store resources (textures, sound buffers, fonts etc.) along with the game objects that use them. This will only cause trouble. Instead, think about storing resources in a centralized place.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Beagle

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Thank you, Nexus!  :)

Quote
As a general advice, don't store resources (textures, sound buffers, fonts etc.) along with the game objects that use them. This will only cause trouble. Instead, think about storing resources in a centralized place.

Aha, I see your point. I'll probably end up making some sort of resource manager which sprites can use then :)

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
As a simple start, you could use the ResourceHolder class template we made for the SFML book.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Beagle

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Thank you! :)

I actually just purchased the SFML book. Already started to read through it!