SFML community forums

Help => Graphics => Topic started by: Trunks7j on November 11, 2009, 01:07:26 am

Title: Problem drawing a sprite -- white square
Post by: Trunks7j on November 11, 2009, 01:07:26 am
Just for some background information, I am developing in SFML on Mac OS 10.5 in XCode, and the image I am trying to display is a .png

In my Scene class I have a vector<sf::Sprite> which contains all the sprites for that scene.  I have populated the array with one sprite:
Code: [Select]

sf::Image img1;
img1.LoadFromFile("images/psnail.png");
sf::Sprite spr1;
spr1.SetImage(img1);
spr1.SetPosition(200, 200);
spriteArray->push_back(spr1);


Now, in my main game loop, I ask the scene for its list of sprites, iterating through and drawing them:
Code: [Select]

app.Clear();
// Draw scene's sprites
std::vector<sf::Sprite>* spriteArray = mainScene->getSprites();
for (int i=0; i<spriteArray->size(); i++)
{
app.Draw(spriteArray->at(i));
}
app.Display();


This draws a sprite in the correct location and size: (200,200) and 32x32, however it is only a white box.  What I dont understand is that if I reset the sprites image in the draw loop right before drawing it, it works; ie:
Code: [Select]

for (int i=0; i<spriteArray->size(); i++)
{
      sf::Image img1;
      img1.LoadFromFile("images/psnail.png");
      spriteArray->at(i).SetImage(img1);
      app.Draw(spriteArray->at(i));
}


This draws the sprite correctly.  Anybody have any idea whats going on?  The code is exactly the same in both places--why would the sprite show up as a white block if I set its image before inserting it into the array?[/code]
Title: Problem drawing a sprite -- white square
Post by: Trunks7j on November 11, 2009, 01:13:07 am
Idiot.  Should have read more forum posts.  I figured out the answer, although that is quite an odd bug for OSX.
Title: Problem drawing a sprite -- white square
Post by: Trunks7j on November 11, 2009, 01:32:19 am
Actually I am still trying and unfortunately it is still not working.  I bound a key to reload all the images, empty the sprite vector and re-add the sprite, and even if I press this after the window has fully loaded the sprite still appears white.... grrrrr  :evil:
Title: Problem drawing a sprite -- white square
Post by: JannoT on November 11, 2009, 02:36:20 am
Can you show us a bit more complete code? It currently looks like the sf::Image might go out of scope and get destroyed.
Title: Problem drawing a sprite -- white square
Post by: Hiura on November 11, 2009, 09:36:23 am
Quote from: "JannoT"
It currently looks like the sf::Image might go out of scope and get destroyed.
that's right. Ths sprite is still in the memory but it's linked image isn't. You have to use anothe storage manager for your images. There are some solutions on the wiki.
Title: Problem drawing a sprite -- white square
Post by: Trunks7j on November 12, 2009, 07:33:54 pm
Okay that makes some sense.  Hiura, I actually did create an ImageManager class for this exact purpose, but perhaps I am not implementing it correctly.  After class I will post some more complete code.  Thanks for the help guys!
Title: Problem drawing a sprite -- white square
Post by: Trunks7j on November 13, 2009, 12:13:53 am
Okay, my problem basically was I had an ImageManager class but it was returning hard Image objects and copying them--now I am returning pointers to images and everything seems to be working just fine.  Thanks guys.
Title: Problem drawing a sprite -- white square
Post by: Hiura on November 13, 2009, 10:27:36 am
You may want to return a reference, but that's not very important.

There are some template managers on the wiki. You can compare them with yours.
Title: Problem drawing a sprite -- white square
Post by: Trunks7j on November 14, 2009, 08:14:58 am
Can you explain the pros/cons of returning a reference in this situation versus a pointer?  I am a little bit confused in these situations and never know which way to go.
Title: Problem drawing a sprite -- white square
Post by: l0calh05t on November 14, 2009, 09:47:46 am
Since references have to be initialized on construction, and can't be NULL (save a few hacks), they are potentially safer than pointers. Otherwise there is no real difference.
Title: Problem drawing a sprite -- white square
Post by: Hiura on November 14, 2009, 11:09:20 am
l0calh05t, we can add that ref are easier to use as there is no need of deference.

I try to use no pointer as often as possible because you have less things to think about.
Title: Problem drawing a sprite -- white square
Post by: Nexus on November 14, 2009, 02:58:40 pm
To sum up:

A pointerA referenceSaying that a reference is safer is only partly true. For example, references also become invalid when their target is destroyed. However, I consider it the better way to use references when a valid object is required, for example at function parameters. Declaring a pointer parameter means to me "either pass a valid object, or nothing".

A lot of contexts require the usage of pointers in C++. By encapsulating those and reducing raw memory handling to a few, isolated places, there is no need to be scared of dangerous pointers. Just use them, when appropriate, and don't use them in the other cases. ;)
Title: Problem drawing a sprite -- white square
Post by: Hiura on November 14, 2009, 04:41:59 pm
Quote from: "Nexus"
For example, references also become invalid when their target is destroyed.
This only happened when you have something like that :

Code: [Select]

int* i = new int;

int& ref = i;

delete i; // ref is invalid from here.


isn't it ?

If I'm right, references modify an object life time. So a reference on a non-manualy allocated object has no risk to become invalid.
Title: Problem drawing a sprite -- white square
Post by: Laurent on November 14, 2009, 05:02:31 pm
Quote
If I'm right, references modify an object life time. So a reference on a non-manualy allocated object has no risk to become invalid.

I think you're wrong
Code: [Select]
A& func()
{
    A a;
    return a;
}

In this case, the returned value will always be invalid. Any good compiler will throw a warning on this code ;)

Apart from that, there is indeed a rule which says that references can increase an object's lifetime, but I think it's only when using a const reference to increase the lifetime of a temporary object. Something like this:
Code: [Select]
const std::string& str = std::string("hello");
I'm not 100% sure though :)
Title: Problem drawing a sprite -- white square
Post by: Nexus on November 14, 2009, 07:38:43 pm
Quote from: "Hiura"
So a reference on a non-manualy allocated object has no risk to become invalid.
That is wrong. If an object with automatic storage class falls out of scope, references to it are invalidated.

Quote from: "Laurent"
I'm not 100% sure though :)
Yes, you are right. Const references are able to be bound to a temporary object and extend its lifetime (if the references themselves are not members of a class). This is a nice rule, since it allows things like this:
Code: [Select]
void foo(const std::string& str);

foo("hello"); // "hello" creates a temporary std::string instance
foo(std::string("hello")); // exactly the same
Title: Problem drawing a sprite -- white square
Post by: Hiura on November 15, 2009, 12:43:40 pm
Yes I was wrong. You two just make me remember what I've read on gotw some time ago. Thanks.