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

Author Topic: Problem returning sf::Texture  (Read 2157 times)

0 Members and 1 Guest are viewing this topic.

BeautiCode

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
Problem returning sf::Texture
« on: July 21, 2014, 04:23:12 am »
//Data.h
class Data
{
public:

    bool playing=false;
    float W_HEIGHT=576,W_WIDTH=768;
    sf::Texture dirt,grass,water,man;
    sf::Sprite layout[9][13];
    sf::Text error;
    sf::Font default_font;
    int tiles[9][13]={
    {2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2}
    }; //1=water,2=dirt,3=grass
};

//Verifications.h
class Verifications : public Data
{
public:
    sf::Texture getObject(int tile);
private:


};

//Verifications.cpp
#include "verifications.h"
sf::Texture Verifications::getObject(int tile)
{
    switch(tile)
    {
    case 1:
        {
            return water;
        } break;
    case 2:
        {
            return dirt;
        } break;
    case 3:
        {
            return grass;
        } break;
    default:
        return dirt;
    //Add "default", return an X or ? or Message.
    }
}

//actions.h
class Actions : public Data
{
public:
    Verifications Ver;
    Actions(sf::RenderWindow* temp) : win(temp)
    {

    }
    void initgame();
    void gameerror();
    void loadscreen();
private:
    sf::RenderWindow* win;
};

//loadscreen() in Actions.h
void Actions::loadscreen()
{
    //win->clear(sf::Color(205,133,63));
    //Ver.getObject(tiles[y][x])

    for(int x=0,y=0;;x++)
    {
        if(x==12) {x=0;y++;}
        if(y>8) {break;}
        layout[y][x].setPosition(x*64,y*64);
        layout[y][x].setTexture(Ver.getObject(tiles[y][x]));
        std::cout<<tiles[y][x];
        std::cout<<Ver.test();
        win->draw(layout[y][x]);
    }
    win->display();
}

 

For some reason it doesn't display the dirt sf::Texture that should be from getObject(). The id is passed into getObject() by tiles[y][ x ] and if it gets 2, it should return the dirt sf::Texture.
But when I change the argument from Ver.getObject(tiles[y][ x ]) to just dirt , it displays everything how it should be.
I even  tried directly passing2into getObject(),but it still doesn't display. So it's a problem with the return

Strelok

  • Full Member
  • ***
  • Posts: 139
    • View Profile
    • GitHub
Re: Problem returning sf::Texture
« Reply #1 on: July 21, 2014, 04:51:01 am »
I'm quite sure getobject(int) calls sf::texture's copy constructor so that you have a copy of dirt every get object. You might want to use a shared pointer or a reference to sf::texture.

BeautiCode

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
Re: Problem returning sf::Texture
« Reply #2 on: July 21, 2014, 04:51:56 am »
I'm quite sure getobject(int) calls sf::texture's copy constructor so that you have a copy of dirt every get object. You might want to use a shared pointer or a reference to sf::texture.
I tried that as-well.

Strelok

  • Full Member
  • ***
  • Posts: 139
    • View Profile
    • GitHub
Re: Problem returning sf::Texture
« Reply #3 on: July 21, 2014, 04:58:59 am »
http://sfml-dev.org/documentation/2.1/classsf_1_1Sprite.php#a3729c88d88ac38c19317c18e87242560 the texture of get object is destroyed right after set texture
That's why only settexture (dirt) works.

BeautiCode

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
Re: Problem returning sf::Texture
« Reply #4 on: July 21, 2014, 05:03:57 am »
I did the reference thing again, and also called loadFromFile() a secondtime, but inside the getObject()function.
Now it works...But why?

Strelok

  • Full Member
  • ***
  • Posts: 139
    • View Profile
    • GitHub
Re: Problem returning sf::Texture
« Reply #5 on: July 21, 2014, 05:17:52 am »
sf::Texture::setTexture(const sf::Texture&, bool) saves a pointer to your sf::Texture. Dirt has the lifespan of Data, while get object copies dirt and creates a temporary sf::Texture that will be destroyed after set texture, now the sprite has an invalid pointer to a texture, leading to an undefined behaviour. By returning a reference to dirt in getobject you almost do the same as settexture(dirt) ensuring that the pointer will be valid as long Data is valid and dirt correctly initialized.
Sorry for the confusion, it's 5:20 AM and I am writing from a tablet :D.
« Last Edit: July 21, 2014, 05:26:15 am by Strelok »

BeautiCode

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
Re: Problem returning sf::Texture
« Reply #6 on: July 21, 2014, 05:39:24 am »
sf::Texture::setTexture(const sf::Texture&, bool) saves a pointer to your sf::Texture. Dirt has the lifespan of Data, while get object copies dirt and creates a temporary sf::Texture that will be destroyed after set texture, now the sprite has an invalid pointer to a texture, leading to an undefined behaviour. By returning a reference to dirt in getobject you almost do the same as settexture(dirt) ensuring that the pointer will be valid as long Data is valid and dirt correctly initialized.
Sorry for the confusion, it's 5:20 AM and I am writing from a tablet :D.
Ooh, alright thank you! :)