Hello,
I’ve been trying to create resource (sprites) manager, but ended up having problem. Idea was like this: image and texture are being loaded into memory only once (those files might be big), Sprites that are being created should point to those resources instead.
That’s for the vision, below something I’ve got so far:
Hpp class file
#ifndef OBJECTS_H
#define OBJECTS_H
#include <SFML/Graphics.hpp>
#include <memory>
class Objects {
public:
Objects();
virtual ~Objects();
void draw ( sf::RenderWindow *window );
protected:
void create ( void );
sf::Sprite foo ( void );
private:
sf::Image image;
sf::Texture texture;
//std::vector < sf::Sprite > sprites; // First approach -> Without pointers, it's working
std::vector < sf::Sprite* > sprites;
//std::vector < std::unique_ptr < sf::Sprite > > sprites; // Third approach - smart ptr's
};
#endif // OBJECTS_H
Cpp Class file:
#include "Objects.hpp"
Objects::Objects() {
image.loadFromFile ( "image.png" ); // just some red 20x20 px square
texture.loadFromImage( image );
create();
}
Objects::~Objects() {
//dtor
}
// Objects::create
void Objects::create ( void ) {
sf::Sprite sprite;
sprite.setTexture( texture );
// sprites.push_back ( sprite ); // First approach - works, but we have unnecesary textures per sprite resisting in memory?
sprites.push_back( &sprite ); // Second approach - not working
// sprites.push_back( std::unique_ptr < sf::Sprite > ( &sprite ) ); // Third approach, not working as well
}// Objects::create
// Objects::draw
void Objects::draw ( sf::RenderWindow *window ) {
//window->draw ( ( sprites[0] ) ); // First working approach
window->draw ( ( *sprites[0] ) ); // Second and Third approach - not working
}// Objects::draw
In
main.cpp, I’m, just creating class object and invoking draw function:
#include <SFML/Graphics.hpp>
#include "Objects.hpp"
int main() {
Objects o;
sf::RenderWindow window(sf::VideoMode( 800, 600 ), "Texture Loading Test!" );
while ( window.isOpen() ) {
sf::Event event;
while ( window.pollEvent( event ) ) {
if ( event.type == sf::Event::Closed ) {
window.close();
}
}// while
window.clear();
o.draw( &window );
window.display();
}// while
return 0;
}
As for Me... it should work
, but (surprise)… it’s not. I believe we have some kind of memory leek here. I assume, the problem lies here (passing reference to object, pointing to null texture):
void Objects::create ( void ) {
sf::Sprite sprite;
sprite.setTexture( texture );
sprites.push_back( &sprite );I know I can ignore the pointers approach, and just stick to “first approach” mentioned above, but to my knowledge it will create unnecessary textures, resisting in memory (for example, creating 100 of sprites will create 100 of additional textures) – is my reasoning correct?
I must say, I’ve got no clue how to fix this...
Any suggestions/hints/leads are most welcomed.
Thank You for help in advance.