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

Author Topic: Incompatibility with sf::Image and stl::list??  (Read 4443 times)

0 Members and 1 Guest are viewing this topic.

RedTheGreen

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • RedTheGreen's Website
    • Email
Incompatibility with sf::Image and stl::list??
« on: October 14, 2012, 06:40:00 am »
Does anyone know if there is an incompatibility here? My animation class runs smoothly every time, but when I try to automate the process of reading several animations by queuing them in an stl::list, they don't show on-screen.

I'm positive the issue is something like this. The function I'm calling to draw it returns the sf::Sprite of the current frame, but it isn't showing anything. The program doesn't crash or anything either, so I'm thinking the Image doesn't stay in memory when it's in a list.

Anybody know anything about this?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #1 on: October 14, 2012, 09:00:33 am »
Can you show the code where you load the images, store them in the list and assign them to the sprites?

You have to be careful about copies that can happen; have a look at the last paragraph of the sprite tutorial.
Laurent Gomila - SFML developer

RedTheGreen

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • RedTheGreen's Website
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #2 on: October 15, 2012, 05:50:45 am »
Animation class
class Animation
{
    sf::Image img;
    std::list<AnimationFrame> frames;
    AnimationFrame currentFrame;
    void CheckFrames();

    public:
    void LoadFromFile( std::string filename );
    void SetPos( float x, float y );
    sf::Sprite Output();
};

Function to load image
void Animation::LoadFromFile( std::string filename )
{
    XMLDocument file;
    file.LoadFile( filename.c_str() );
    XMLElement* root = file.RootElement();
    img.LoadFromFile( root->Attribute( "image" ) );
    int w, h;
    w = root->IntAttribute( "w" );
    h = root->IntAttribute( "h" );
}
 

Function to store in list
void BuildMapFromFile( std::string filename )
{
    XMLDocument file;
    file.LoadFile( filename.c_str() );
    XMLElement* root = file.RootElement();

    //obj_animation
    for( XMLElement* animation = root->FirstChildElement( "animation" ); animation; animation = animation->NextSiblingElement( "animation" ) )
    {
        //object
        object new_object;
        new_object.type = "animation";
        int depth = animation->IntAttribute( "depth" );
        new_object.depth = depth;
       
        new_object._animation.LoadFromFile( animation->Attribute( "source" ) ); //loads image
        new_object._animation.SetPos( animation->IntAttribute( "x" ), animation->IntAttribute( "y" ) );

        std::list<object>::iterator i = q_object.begin();
        bool varadded = false;
        while( i != q_object.end() )
        {
            if( i->depth > depth )
            {
                q_object.insert( i, new_object );
                varadded = true;
                i = q_object.end();
            }
            else ++i;
        }
        if( varadded == false ) q_object.push_back( new_object );
    }
}

The animation class loads its own image, which is kept inside the class (not the best idea, I know). The class itself is moved into the list.

EDIT: I just tried setting the sprites to a globally-declared image, and it failed as well.
« Last Edit: October 15, 2012, 05:58:30 am by RedTheGreen »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #3 on: October 15, 2012, 08:02:31 am »
Quote
The class itself is moved into the list.
So this is exactly what is described in the tutorial. Don't forget that the list stores a copy of your object, and that a copied sprite will still use the same image as its source, not the copy of the image which is often made at the same time. It's hard to verify here because you don't show all the relevant parts of your code.
Laurent Gomila - SFML developer

RedTheGreen

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • RedTheGreen's Website
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #4 on: October 16, 2012, 02:47:39 am »
That's something I wasn't really thinking about. I'll keep it in mind from now on.

That's now fixed, but it's still failing. Even if I use a globally-declared image, it fails.
« Last Edit: October 16, 2012, 04:21:32 am by RedTheGreen »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #5 on: October 16, 2012, 08:06:34 am »
Then show a complete and minimal code that reproduces this new problem.
Laurent Gomila - SFML developer

RedTheGreen

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • RedTheGreen's Website
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #6 on: October 17, 2012, 05:18:06 am »
Here's a modified copy of my code in a Code::Blocks project. It requires SFML 1.6.

https://sites.google.com/a/redthegreen.com/files/Flow-Dev.zip?attredirects=0&d=1

There's also a new issue of crashing that only occurs when compiling under Release. If you compile under Debug, it won't crash. Keep that in mind when testing.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #7 on: October 17, 2012, 07:46:44 am »
Laurent Gomila - SFML developer

RedTheGreen

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • RedTheGreen's Website
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #8 on: October 18, 2012, 06:49:46 am »
Woops. I guess I should have read that first.

Anyway, here's a simple example I whipped up quickly. This should be a bit easier to read.

#include <SFML/Graphics.hpp>
#include <string>
#include <list>

struct ComplexImage
{
    sf::Image img;
    std::string file;
};

std::list<ComplexImage> buffer_image;

sf::Image GetImage( std::string filename )
{
    std::list<ComplexImage>::iterator i = buffer_image.begin();
    bool varfound = false;
    while( i != buffer_image.end() )
    {
        if( i->file == filename )
        {
            varfound = true;
            return i->img;
        }
        else ++i;
    }
    if( varfound == false )
    {
        //create new image
        ComplexImage new_image;
        new_image.img.LoadFromFile( filename.c_str() );
        new_image.file = filename;

        buffer_image.push_back( new_image );
        return GetImage( filename );
    }
}

int main( int argc, char* argv[] )
{
    sf::RenderWindow game( sf::VideoMode( 800, 600, 32 ), "App Title" );
    sf::Event event;

    sf::Sprite test_sprite;
    test_sprite.SetImage( GetImage( "ball.png" ) );
    test_sprite.SetPosition( 40, 40 );

    while( game.IsOpened() )
    {
        while( game.GetEvent( event ) )
        {
            //if window is closed or Escape key is pressed, close the game
            if( event.Type == sf::Event::Closed or ( event.Type == sf::Event::KeyPressed && event.Key.Code == sf::Key::Escape ) ) game.Close();
        }

        //clear display
        game.Clear( sf::Color( 100, 149, 237 ) );

        //draw sprite
        game.Draw( test_sprite );

        //update display
        game.Display();
    }

    return EXIT_SUCCESS;
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #9 on: October 18, 2012, 08:13:09 am »
Thanks :)

With this code I spotted the problem in no more than 2 seconds.

GetImage returns a temporary copy of the original image, which is destroyed immediately after being given to the sprite. You must return a reference (sf::Image&).
Laurent Gomila - SFML developer

RedTheGreen

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • RedTheGreen's Website
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #10 on: October 20, 2012, 04:46:44 am »
Alright! Thank you! I was planning on doing that anyway, but I didn't realize I had to.

kaB00M

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Caffeware
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #11 on: October 25, 2012, 04:28:27 am »
Why not use std::map?

std::map<string, ComplexImage> buffer_images;

if (buffer_images.find(name) != buffer_images.end())
{
    return buffer_images[name];
}

//add into map
buffer_images[name] = ComplexImage; //etc
//etc
 
« Last Edit: October 25, 2012, 04:32:28 am by kaB00M »



RedTheGreen

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • RedTheGreen's Website
    • Email
Re: Incompatibility with sf::Image and stl::list??
« Reply #12 on: December 04, 2012, 04:43:21 am »
Maybe I should. Good idea.