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

Author Topic: Image is white ()  (Read 4205 times)

0 Members and 1 Guest are viewing this topic.

coolhome

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
Image is white ()
« on: January 28, 2009, 02:15:47 pm »
ok first just let me dump my code =)

Code: [Select]
struct sprite {
sf::Image Image;
sf::Sprite Sprite;
int x;
int y;
float rotation;
sf::IntRect SubRect;
};

typedef std::pair<std::string, sprite> value_type;

std::map<std::string, sprite> sprites;
std::map<std::string, sprite>::iterator spritesIterator;

void loadimage(std::string key, std::string Filename) {
sprite _spriteStruct;
sf::Image _load;
sf::Sprite _sprite;
if(! _load.LoadFromFile(Filename)) {
//error
}
_spriteStruct.Image = _load;
_spriteStruct.Sprite = _sprite;
_spriteStruct.Sprite.SetImage(_spriteStruct.Image);
sprites.insert(std::pair<std::string,sprite>(key,_spriteStruct));
}


Ok well i understand this
Quote
You have to be particularly careful when manipulating images. A sf::Image instance is a resource which is slow to load, heavy to copy and uses a lot of memory.

A lot of people, especially beginners, will just put an instance of sf::Image wherever they have an instance of sf::Sprite, because it may seem the simplest way to draw something. The fact is that it's generally a bad idea. The most obvious problem is when copying such objects (just putting them into an array generates copies) : the sprites will most likely appear white. The reason is that a sprite only points to an external image it doesn't own one, so when the image is copied the sprite has to be updated to point to the new copy of the image. This is quite easy to handle, you just have to define a copy constructor for such classes holding (or deriving from) a sprite and an image

but i dont understand exactly what im doing wrong...[/code]
CoderZilla - Everything Programming

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Image is white ()
« Reply #1 on: January 28, 2009, 02:30:04 pm »
The image bound to the sprite will be destroyed right after loadimage returns. You have to make it live at least as long as the sprites uses it.
Laurent Gomila - SFML developer

coolhome

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
Image is white ()
« Reply #2 on: January 28, 2009, 02:33:20 pm »
Nevermind you can close topic I already solved it I got it...

Code: [Select]
struct spriteStruct {
sf::Image Image;
sf::Sprite Sprite;
int x;
int y;
float rotation;
sf::IntRect SubRect;
};

typedef std::pair<std::string, spriteStruct> value_type;

std::map<std::string, spriteStruct> sprites;
std::map<std::string, spriteStruct>::iterator spritesIterator;

void loadimage(std::string key, std::string Filename) {
spriteStruct _spriteStruct;
sprites.insert(std::pair<std::string,spriteStruct>(key,_spriteStruct));
sprites[key].Image.LoadFromFile(Filename);
sprites[key].Sprite.SetImage(sprites[key].Image);
}


EDIT: Thanks for that info and I love SFML a lot more then SDL!
CoderZilla - Everything Programming

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Image is white ()
« Reply #3 on: January 28, 2009, 03:41:48 pm »
But you will begin to hate it when you don't start to optimize your program in a way that it doesn't consume a huge amount of memory. :)
Do I get you right that you're loading an image for *each sprite*?

You said you understood the following paragraph from the SFML tutorials:
Quote
A lot of people, especially beginners, will just put an instance of sf::Image wherever they have an instance of sf::Sprite, because it may seem the simplest way to draw something. The fact is that it's generally a bad idea.

But you didn't. :) Please load an image only once. Images can and should be shared between multiple sprites.

coolhome

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
Image is white ()
« Reply #4 on: February 01, 2009, 11:49:27 pm »
so im back and this is what i got :P

ImageManager.hpp
Code: [Select]
#pragma once

#include "Includes.hpp"

class ImageManager {
public:
typedef pair<string, sf::Image*> Images;
typedef map<string, sf::Image*> ImagesMap;
ImagesMap manager;
ImageManager();
~ImageManager();
bool Load(const string &Key, const string &Filename);
sf::Image* Get(const string &Key);
};


and ImageManager.cpp
Code: [Select]
#include "Includes.hpp"

ImageManager::ImageManager() {

}

ImageManager::~ImageManager() {
while(manager.begin() != manager.end()) {
delete manager.begin()->second;
manager.erase(manager.begin());
}
}

bool ImageManager::Load(const string &Key, const string &Filename) {
    sf::Image* image = new sf::Image();
    if(! image->LoadFromFile(Filename) ) {
        delete image;
        image = NULL;
return false;
} else {
manager.insert(Images(Key, image));
return true;
}
}

sf::Image* ImageManager::Get(const string &Key) {
sf::Image *resource = NULL;
ImagesMap::iterator it = manager.find(Key);
if(it != manager.end()) {
resource = it->second;
}
return resource;
}


Example:
Code: [Select]
ImageManager manager;
sf::Sprite mouse;
if(! manager.Load("mouse", "mouseGraphic.gif")) {
//error here
}
mouse.SetImage(*manager.Get("mouse"));


Do I always need to add the * when setting the image? just wondering if there is a way to remove it... Also the imagemanager class isn't finished yet >.> got some things to add like checking if the key already exists in the map
CoderZilla - Everything Programming

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Image is white ()
« Reply #5 on: February 02, 2009, 02:28:12 am »
Quote from: "coolhome"
Do I always need to add the * when setting the image? just wondering if there is a way to remove it...

Just return a reference instead of a pointer. ;)
Code: [Select]
sf::Image& ImageManager::Get(const std::string &Key);
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

coolhome

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
Image is white ()
« Reply #6 on: February 02, 2009, 03:00:23 am »
Quote from: "Nexus"
Quote from: "coolhome"
Do I always need to add the * when setting the image? just wondering if there is a way to remove it...

Just return a reference instead of a pointer. ;)
Code: [Select]
sf::Image& ImageManager::Get(const std::string &Key);

wow I feel like a noob now :P

wait I am kind of new to C++ >.< nvm
CoderZilla - Everything Programming

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Image is white ()
« Reply #7 on: February 02, 2009, 07:46:17 am »
Quote
Just return a reference instead of a pointer.

Then you'll have to use exceptions to handle errors, or return a dummy image.
Laurent Gomila - SFML developer