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

Author Topic: Best way to load the same image multiple times  (Read 11678 times)

0 Members and 1 Guest are viewing this topic.

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
Best way to load the same image multiple times
« on: November 16, 2010, 11:15:01 am »
Hi,
I'm trying to write a program with a class called wBullet that calls a Sprite with a png image.
This class bullet will create at least 100 objects, and so I was wondering what's the best way to load the same image so many times?

Here's my prototype class:

Code: [Select]
//bullet.hpp

class wBullet
{
    int speed;
    double x,y;
    Sprite bullet;
    wBullet();
};



Code: [Select]
//bullet.cpp
wBullet::wBullet()
{
    bullet.LoadFromFile("b.png");
}



Should I use Sprite::LoadFromFile every time? Will it cause any impact? Or should I try Sprite::LoadFromMemory?

Also, what would be the best way to store all these objects?
An array:
wBullet o1["size of array"]
A vector :
vector<wBullet> o1;
Or anything else?

I understand these are probably newbie questions, but I'm fairly new to C++.

Thanks in advance, keep up the great work!

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Best way to load the same image multiple times
« Reply #1 on: November 16, 2010, 12:11:51 pm »
Sprite doesn't load images. Sprite render images. To load an image you use sf::Image.

And you don't want to load the same image several times. You load one image one time and have several sprites use that image.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Best way to load the same image multiple times
« Reply #2 on: November 16, 2010, 12:19:29 pm »
Does your bullet need to store the image and the renderer (that is, a sprite) or does it only need to have a renderer ? You could store all your image elsewhere, like in a manager (see manager on the wiki page of the site for some examples).

My point is, you have to structure your classes a little bit more; make some relations between them.
SFML / OS X developer

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
Best way to load the same image multiple times
« Reply #3 on: November 16, 2010, 03:15:34 pm »
Quote from: "Groogy"
Sprite doesn't load images. Sprite render images. To load an image you use sf::Image.

And you don't want to load the same image several times. You load one image one time and have several sprites use that image.

Ah yes, I'm sorry, I rushed the code and didn't even compile it since I was planning the structure on a paper.
The code I had in mind would be:
Code: [Select]
//bullet.cpp
wBullet::wBullet()
{
    Image temp;
    temp.LoadFromFile("b.png");
    bullet.SetImage(temp);
}


But this loads the same image several times right? And there's no need for it. However I'm not sure what to do to prevent this.

Quote from: "Hiura"
Does your bullet need to store the image and the renderer (that is, a sprite) or does it only need to have a renderer ? You could store all your image elsewhere, like in a manager (see manager on the wiki page of the site for some examples).

My point is, you have to structure your classes a little bit more; make some relations between them.

Nope, it doesn't need to store the image, just the renderer. I'm going to check the managers out then.
Any more advices are greatly welcome.

And sorry for my rusty English, it's not my first language  :(

Thanks in advance again

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Best way to load the same image multiple times
« Reply #4 on: November 16, 2010, 03:39:21 pm »
Quote from: "Contadotempo"

Code: [Select]
//bullet.cpp
wBullet::wBullet()
{
    Image temp;
    temp.LoadFromFile("b.png");
    bullet.SetImage(temp);
}


But this loads the same image several times right?
Yes but it is also destroyed at the end of the function thus you'll get a white sprite (no texture).
SFML / OS X developer

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
Best way to load the same image multiple times
« Reply #5 on: November 17, 2010, 02:45:58 pm »
Quote from: "Hiura"
Yes but it is also destroyed at the end of the function thus you'll get a white sprite (no texture).

Ah let me fix that. I'm planning without testing and these things happen. This is how I have it:
Code: [Select]
//bullet.hpp
using namespace sf;

class wBullet
{
    int speed;
    double x,y;
    Sprite bullet;
    Image bHolder;
    wBullet();
};

Code: [Select]
//bullet.cpp
wBullet::wBullet()
{
    bHolder.LoadFromFile("b.png");
    bullet.SetImage(bHolder);
}

I couldn't find a manager that would suit this situation. Where could I hold the image? Store it in another class and then wBullet would inherit the values from that class?
Not sure if it's a good idea.

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Best way to load the same image multiple times
« Reply #6 on: November 17, 2010, 03:08:26 pm »
No, what would be preferred and simple would to have a std::map<std::string, sf::Image> to keep track of the images in a "ResourceManager" class. The usage would be something like:

Code: [Select]

vBullet::vBullet()
{
        sf::Image& image = globalImageManager.Load("bullet_image.png");
        mySprite.SetImage( image );
        // .... other code
}


Remember that in the ResourceManager::Load function to first check in the map instance if the image might have already been loaded, if not then load it into the map instance.

Of course here's tons of optimizations that can be done, but first get it to work right before even thinking about that.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

heishe

  • Full Member
  • ***
  • Posts: 121
    • View Profile
Best way to load the same image multiple times
« Reply #7 on: November 17, 2010, 05:40:40 pm »
you can write a simple generic ResourceManager class using templates that manages all kinds of stuff:


Code: [Select]


template <class T>
class ResourceManager
{
public:
    //......
    void Store(string name, T *obj)
    {
         storage[name]=T;
    }

    T* Get(string name) { return storage[name]; }
private:
map storage<string, T*>
}

//Usage:

void xyz()
{
      ResourceManager<Image> imageManager;
      //pointer is important, otherwise it gets deleted at the end of the block
      Image *i = new Image; i->LoadFromFile("...");
     imageManager.Store(i);
     i = imageManager.Get("...");
}


I left out namespaces for the most part cause it's bothersome to write.

You may want to attach the singleton pattern to the ResourceManager classes. But I won't go into that, you can look it up on google.

Xorlium

  • Jr. Member
  • **
  • Posts: 84
    • View Profile
Best way to load the same image multiple times
« Reply #8 on: November 17, 2010, 06:02:22 pm »
You could also make the image static, so it's shared by all the bullets. This is assuming nothing else will use that same image.

Code: [Select]

class wBullet
{
    int speed;
    double x,y;
    Sprite bullet;
    static Image bHolder;
    wBullet();
};


And then in the cpp file (and this is important) do something like this (not in any function)

Code: [Select]

Image wxBullet::bHolder;


and then in the constructor for wBullet:
Code: [Select]

wBullet::wBullet()
{
  static bool hasImageBeenLoaded = false;
  if (!hasImageBeenLoaded)
  {
    Image.LoadFromFile("myfile.png");
    hasImageBeenLoaded = true;
  }
  //other stuff
}

Canadadry

  • Hero Member
  • *****
  • Posts: 1081
    • View Profile
Best way to load the same image multiple times
« Reply #9 on: November 17, 2010, 06:17:30 pm »
there is a great image manager on the wiki. Why does anyone go check the wiki ?

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Best way to load the same image multiple times
« Reply #10 on: November 17, 2010, 06:32:46 pm »
Quote from: "mooglwy"
there is a great image manager on the wiki. Why does anyone go check the wiki ?
Yes, there are ton of them. No need to recreate the wheel. (However, this one is not the best : not as flexible as I want. But let's skip this for another time, would you ? :wink: )

About static : here it isn't the best idea. What would you do if you want a special bullet to look like no one else ? Well, you have to choice but both are not optimal :
(a) create a new class by inheritance and create a new static var.
(b) do sprite.SetImage(...) on your special bullet and save the image elsewhere (eg with a kind of manager).
SFML / OS X developer

Xorlium

  • Jr. Member
  • **
  • Posts: 84
    • View Profile
Best way to load the same image multiple times
« Reply #11 on: November 18, 2010, 01:19:02 am »
Yeah, I know static wouldn't be very extensible, but that's exactly what this person asked at the beginning, (s)he wanted the same image to be shared by all the bullets. I just pointed out that if you want some data to be shared between all objects of a class, you make it "static".

If it's a big project, then yeah, you need one. But if it's for a homework that's due tomorrow, and you don't want different bullets to have different images, whatever, why not?

Xorlium

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Best way to load the same image multiple times
« Reply #12 on: November 18, 2010, 02:48:04 pm »
Well, when I create a class or something I try to make it as flexible as possible. It therefore can be reused in another project very quickly. Reusability is the key of success.  :wink:
SFML / OS X developer

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
Best way to load the same image multiple times
« Reply #13 on: November 21, 2010, 09:32:35 am »
Hey, sorry for the late reply.
mooglwy is right, I need to check the wiki more often sorry about that :P . Hope this isn't considered a waste of time.

I'll be trying to make my own manager based on std::map.
This way I'll learn my steps better and earn more experience I guess.
Thanks everyone!

Quote from: "Hiura"

Reusability is the key of success.

Very good point  :)

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
Best way to load the same image multiple times
« Reply #14 on: November 22, 2010, 04:43:21 pm »
Just one quick question, sorry for bumping the topic again:
If I wanted to destroy the manager completely, would using map::clean() on the destructor be enough? I'm very afraid of memory leaks.

 

anything