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

Author Topic: How to avoid "the white square problem"?  (Read 8052 times)

0 Members and 1 Guest are viewing this topic.

kim366

  • Newbie
  • *
  • Posts: 35
    • View Profile
How to avoid "the white square problem"?
« on: December 27, 2014, 09:47:22 pm »
I am experiencing  "the white square problem" (http://www.sfml-dev.org/tutorials/2.0/graphics-sprite.php#the-white-square-problem). I have 2 std::vectors, one sf::Texture and one sf::Sprite, using that Texture. Both are being declared, the texture is being loaded from a file and the Sprite is using the texture, all in a while loop. So how am I supposed to make the texture last outside the while loop. what about
sf::Texture *tex = new sf::Texture
or something like that? I have never used that before and I don't really know what it does and how to use it. What is very strange, is that some Sprites work! the first 2 don't, but the third for example does. And some of the other sprites have wrong textures. But the vectors are being declared outside the loop, so I am able to draw and compile everything just fine.

Thank you for your help!
« Last Edit: December 27, 2014, 10:07:36 pm by kim366 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11053
    • View Profile
    • development blog
    • Email
Re: How to avoid "the white square problem"?
« Reply #1 on: December 27, 2014, 11:24:57 pm »
If you have no idea how to use std::vector or how the new keyword works, you should first learn C++ with a good C++ book.
SFML is very simple as such one usually can do "something" without actually knowing C++, but as soon as you try something more complex, you'll fail and it's not because of SFML, but because of lacking C++ knowledge. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Neil

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: How to avoid "the white square problem"?
« Reply #2 on: December 28, 2014, 01:08:38 am »
Create a global std::map<std::string, sf::Texture> object, where the key name is the name of the texture or its file path or something. This then gives you easy access to the textures that lasts for your whole program.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11053
    • View Profile
    • development blog
    • Email
Re: How to avoid "the white square problem"?
« Reply #3 on: December 28, 2014, 01:10:43 am »
No, don't do that! Do NOT use globals, especially not with SFML resources. It will only create odd issues and crashes and you still wouldn't have learned anything about C++ code design.
« Last Edit: December 28, 2014, 01:15:56 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Neil

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: How to avoid "the white square problem"?
« Reply #4 on: December 28, 2014, 01:29:49 am »
It will work for a quick and dirty solution.

There's a global variable right here:
SFML\Graphics\ImageLoader.cpp:78

I agree that in general global variables are bad and should be avoided.

What issue will be caused by using sf::Texture as a global variable? Regardless of the goodness of the design, nothing in the spec precludes it, so it must be supported.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: How to avoid "the white square problem"?
« Reply #5 on: December 28, 2014, 01:36:58 am »
The construction/destruction order of global variables is undefined (unspecified?) in C++.  There are many threads in this forum about people encountering strange crashes because they made their RenderWindows or resource classes global, and there's simply nothing SFML can do to prevent such crashes.

More importantly, globals are usually evil anyway, and there's no reason why your texture map needs to be global.  Simply construct it in main() and pass it to whoever needs it, like any other major dependency or subsystem.  But aside from the "global" thing, what you said sounds right to me: A simple std::map does the job fine as long as it's not global.


@kim366: To directly answer your original question, it's probably because std::vector is allowed to move/copy its elements around.  Normally this is fine, but here you have a vector of objects that contain pointers to the objects in another vector, so that's pretty much guaranteed to break (which is not in any way unique to SFML).  A "stable" container like a std::map will not move its elements around, which is why it's the simplest way to solve this problem.
« Last Edit: December 28, 2014, 01:47:43 am by Ixrec »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11053
    • View Profile
    • development blog
    • Email
AW: How to avoid "the white square problem"?
« Reply #6 on: December 28, 2014, 01:45:08 am »
So you assume the OP wants a dirty hack to solve his issue?

The destruction order of global objects is undefined. Some internal design of SFML requires working with global variables as such your texture object could be destroyed after SFML's resources, thus causing crashes.
Besides that, SFML's OpenGL context management isn't written to handle global resources well, if at all.

And no I won't participate in a discussion about globals. There's enough of that material on the internet.

Help is usually not about giving the asking person whatever they want, regardless of the cost, but it's more about helping so they can start help themselves.
Thus providing ugly hacks or writing them all the code is only short sighted and doesn't really help them. ;)
« Last Edit: December 28, 2014, 01:47:44 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Neil

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: How to avoid "the white square problem"?
« Reply #7 on: December 28, 2014, 01:58:31 am »
I'm sorry for suggesting that to the OP.
It would be a good solution if implemented in Ixrec's way.

kim366

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: How to avoid "the white square problem"?
« Reply #8 on: December 28, 2014, 09:34:21 am »
I know C++, I just wanted to know if that's what I'm looking for, or does somebody have a better solution? I am not making the Project OOP yet, so everything is in main. The 2 vectors are declared at the top of main, the while loop if further down. But the texture doesn't seem to load into that vector, but strangely it sometimes does.

Neil

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: How to avoid "the white square problem"?
« Reply #9 on: December 28, 2014, 01:40:32 pm »
If you want to use vector, try std::vector<std::unique_ptr<sf::Texture>>. This will ensure textures have an unchanging address when expanding the vector.