SFML community forums

Help => Graphics => Topic started by: lockandstrike on August 08, 2013, 04:29:50 pm

Title: [SOLVED]Loading charset
Post by: lockandstrike on August 08, 2013, 04:29:50 pm
So I'm doing this project and for my character sprite i'll be using an RPG Maker charset. For my project more understandable i've got it divided in functions. When i load the png file that contains my charset it doesnt show anything. It goes like an enormous white square. Here's the code:

#include <SFML/Graphics.hpp>

sf::Texture loadStuff()
{
          sf::Texture gmChar;

          if(!gmChar.loadFromFile("Resource/charsetfinal.png")){
                  //return EXIT_FAILURE;
          }
                  return gmChar;


}

void defCharset(sf::Sprite *gmCharacther_semiIdle, sf::Sprite *gmCharachter_stage1, sf::Sprite *gmCharachter_stage2)
{

  sf::Texture gmChar;

  gmChar = loadStuff();


  gmCharacther_semiIdle->setTexture(gmChar);
  gmCharachter_stage1->setTexture(gmChar);
  gmCharachter_stage2->setTexture(gmChar);

}
 

so after the blank square i tried putting it all in the same function. But with that the game didn't even start. Here's the code for that:

#include <SFML/Graphics.hpp>

void defCharset(sf::Sprite *gmCharacther_semiIdle, sf::Sprite *gmCharachter_stage1, sf::Sprite *gmCharachter_stage2)
{

  sf::Texture gmChar;

  if(!gmChar.loadFromFile("Resource/charsetfinal.png")){
     //return EXIT_FAILURE;
  }


  gmCharacther_semiIdle->setTexture(gmChar);
  gmCharachter_stage1->setTexture(gmChar);
  gmCharachter_stage2->setTexture(gmChar);

}



PS: This is only part of the program. I think it's obvious but...
Title: Re: Loading charset
Post by: Laurent on August 08, 2013, 04:36:59 pm
Please read the "White square problem" section at the end of the sprite tutorial.
Title: Re: [SOLVED]Loading charset
Post by: lockandstrike on August 08, 2013, 04:50:17 pm
Can you tell me why the 2nd code doesn't work?
Title: Re: [SOLVED]Loading charset
Post by: eXpl0it3r on August 08, 2013, 04:53:54 pm
Can you tell me why the 2nd code doesn't work?
What second code?

Otherwise:
Please read the "White square problem" section at the end of the sprite tutorial.
Title: Re: [SOLVED]Loading charset
Post by: lockandstrike on August 08, 2013, 04:57:23 pm
Ok so how do i write a function that's equivalent to the one i initially wrote but that doesn't causes problems?
Title: Re: Loading charset
Post by: Laurent on August 08, 2013, 05:37:48 pm
Your texture is local to the function, it is destroyed when it returns. You must keep the texture alive as long as it is used by sprites.
Title: Re: Loading charset
Post by: lockandstrike on August 08, 2013, 05:51:54 pm
so what if i use pointers?
Title: Re: Loading charset
Post by: lockandstrike on August 08, 2013, 07:45:07 pm
I think I've made a breakthrough but I'm still getting the error I posted in the OP. The game opens and closes in the blink of an eye. But anyway here is my code. If could tell what I'm doing wrong I'd be really appreciated.

main.cpp

#include <SFML/Graphics.hpp>

void defCharset(sf::Sprite *,sf::Sprite *,sf::Sprite *,std::string );

//RenderWindow and bla,bla,bla...

sf::Sprite gmChar_sm;
sf::Sprite gmChar_s1;
sf::Sprite gmChar_s2;

defCharset(&gmChar_sm, &gmChar_s1, &gmChar_s2, "Resource/charsetfinal.png");

//game loop and all the other stuff
 

chars.cpp

#include <SFML/Graphics.hpp>

void defCharset(sf::Sprite *gmCharacther_semiIdle,sf::Sprite *gmCharacther_stage1,sf::Sprite *gmCharacther_stage2, std::string filename)
{
        sf::Texture gmChar;
        if (!gmChar.loadFromFile(filename)){
                //
        }

        gmCharacther_semiIdle->setTexture(gmChar);
        gmCharachter_stage1->setTexture(gmChar);
        gmCharachter_stage2->setTexture(gmChar);

}
Title: Re: Loading charset
Post by: Ixrec on August 08, 2013, 08:58:37 pm
Could you post the "game loop and all the other stuff" code?
Title: Re: Loading charset
Post by: lockandstrike on August 08, 2013, 09:12:35 pm
I'm gonna paste the entire main.cpp code just dont give a crap about commented code.

#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>


const int AppHeight = 540;
const int AppWidth = 1020;

void defCharset(sf::Sprite *, sf::Sprite *, sf::Sprite *, std::string);

int main()
{
  sf::RenderWindow Window(sf::VideoMode(AppWidth,AppHeight,32),"TESTE", sf::Style::Close | sf::Style::Titlebar);

  //sf::Music backgroundMusic;

  /*if(!backgroundMusic.openFromFile("Resource/FromHere.ogg")){
          return EXIT_FAILURE;
    }*/

////////////////////////////////////////////////////////////////////////

  float x = 90;
  float y = 40;

  int mute = 0;

  sf::Sprite gmChar_sm;
  sf::Sprite gmChar_s1;
  sf::Sprite gmChar_s2;

  defCharset(&gmChar_sm, &gmChar_s1, &gmChar_s2,"Resource/charsetfinal.png");


  gmChar_sm.setPosition(x,y);

////////////////////////////////////////////////////////////////////////



  //backgroundMusic.play();

  while(Window.isOpen()){

    sf::Event event;
    while(Window.pollEvent(event)){

      switch(event.type){

      case sf::Event::Closed:
          Window.close();
          break;

      case sf::Event::KeyPressed:
          switch(event.key.code){
          case sf::Keyboard::Escape:
                  Window.close();
                  break;

          case sf::Keyboard::Down:

                  y++;

                  gmChar_sm.setPosition(x,y);

                  break;

          case sf::Keyboard::Up:

                  y--;

                  gmChar_sm.setPosition(x,y);

                  break;

          case sf::Keyboard::Right:

                  x++;

                  gmChar_sm.setPosition(x,y);

                  break;

          case sf::Keyboard::Left:

                  x--;

                  gmChar_sm.setPosition(x,y);

                  break;

          case sf::Keyboard::M:
                  if (mute == 0){
                          mute++;
                  }
                  else if(mute == 1){
                          mute--;
                  }

                  if(mute == 1){
                          //backgroundMusic.stop();
                  }
                  else if(mute == 0){
                          //backgroundMusic.play();
                  }

                  break;
          }
          break;

      case sf::Event::LostFocus:
          //backgroundMusic.pause();
          break;

      case sf::Event::GainedFocus:
          if(mute == 0){
                  //backgroundMusic.play();
          }

          else{

          }
          break;

      default:
          break;

      }

      Window.clear(sf::Color(250,0,0));
      Window.draw(gmChar_sm);
      Window.display();

    }
  }
}
 
Title: Re: Loading charset
Post by: Ixrec on August 08, 2013, 10:58:50 pm
I'm not sure if this is the root problem, but I noticed that your clear/draw/display lines are inside the while(Window.pollEvent(event)) loop.  That means the window will only get updated on frames where an event happens.  You probably want those lines to be inside the while(Window.isOpen()) loop but outside the while(Window.pollEvent(event)) loop, so the window gets updated every frame while it's still open.
Title: Re: Loading charset
Post by: G. on August 09, 2013, 05:36:23 am
As Laurent and the tutorial said: "Your texture is local to the function, it is destroyed when it returns. You must keep the texture alive as long as it is used by sprites."

gmChar is local to defCharset, thus it is destroyed at the end of the function. It is not copied inside an sf::Sprite when you call setTexture, the sprite is only keeping a link to the texture. If the texture is destroyed the sprite doesn't know what to display anymore and display a white square instead.
So, keep your sf::Texture alive, it's basic C++ scope.
Title: Re: Loading charset
Post by: Ivan on August 09, 2013, 10:27:11 am
As they said, you need to define the texture in main code and pass it as a parameter in defCharset.

chars.h
#include <SFML/Graphics.hpp>

void defCharset(sf::Texture *gmChar, sf::Sprite *gmCharacther_semiIdle,sf::Sprite *gmCharacther_stage1, sf::Sprite *gmCharacther_stage2, std::string filename);
 

chars.cpp
#include "chars.h"

void defCharset(sf::Texture *gmChar, sf::Sprite *gmCharacther_semiIdle,sf::Sprite *gmCharacther_stage1,sf::Sprite *gmCharacther_stage2, std::string filename)
{
    if (!gmChar->loadFromFile(filename)){
    }

    gmCharacther_semiIdle->setTexture(*gmChar);
    gmCharacther_stage1->setTexture(*gmChar);
    gmCharacther_stage2->setTexture(*gmChar);
}
 

main.cpp
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include "chars.h"

const int AppHeight = 540;
const int AppWidth = 1020;

int main()
{
  sf::RenderWindow Window(sf::VideoMode(AppWidth,AppHeight,32),"TESTE", sf::Style::Close | sf::Style::Titlebar);

  //sf::Music backgroundMusic;
  /*if(!backgroundMusic.openFromFile("Resource/FromHere.ogg")){
      return EXIT_FAILURE;
    }*/

////////////////////////////////////////////////////////////////////////

  float x = 90;
  float y = 40;

  int mute = 0;

  sf::Sprite gmChar_sm;
  sf::Sprite gmChar_s1;
  sf::Sprite gmChar_s2;
  sf::Texture gmChar;   // <-- create texture

  defCharset(&gmChar, &gmChar_sm, &gmChar_s1, &gmChar_s2,"cb.bmp");

  gmChar_sm.setPosition(x,y);
 
  ....
 
Title: Re: Loading charset
Post by: lockandstrike on August 09, 2013, 11:43:43 am
Thanks Ivan. It worked. I can finally load all my textures right. Thanks alot.
Title: Re: [SOLVED]Loading charset
Post by: G. on August 09, 2013, 12:45:21 pm
Good thing that you learned what the lifetime of a variable is and finally managed to make it work. :)
Title: Re: [SOLVED]Loading charset
Post by: Ivan on August 09, 2013, 12:59:38 pm
Good thing that you learned what the lifetime of a variable is and finally managed to make it work. :)

 I can't say it better :)