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

Author Topic: [SOLVED]Loading charset  (Read 5033 times)

0 Members and 1 Guest are viewing this topic.

lockandstrike

  • Newbie
  • *
  • Posts: 32
    • View Profile
[SOLVED]Loading charset
« 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...
« Last Edit: August 09, 2013, 11:44:18 am by lockandstrike »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Loading charset
« Reply #1 on: August 08, 2013, 04:36:59 pm »
Please read the "White square problem" section at the end of the sprite tutorial.
Laurent Gomila - SFML developer

lockandstrike

  • Newbie
  • *
  • Posts: 32
    • View Profile
Re: [SOLVED]Loading charset
« Reply #2 on: August 08, 2013, 04:50:17 pm »
Can you tell me why the 2nd code doesn't work?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10801
    • View Profile
    • development blog
    • Email
Re: [SOLVED]Loading charset
« Reply #3 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.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

lockandstrike

  • Newbie
  • *
  • Posts: 32
    • View Profile
Re: [SOLVED]Loading charset
« Reply #4 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?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Loading charset
« Reply #5 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.
Laurent Gomila - SFML developer

lockandstrike

  • Newbie
  • *
  • Posts: 32
    • View Profile
Re: Loading charset
« Reply #6 on: August 08, 2013, 05:51:54 pm »
so what if i use pointers?

lockandstrike

  • Newbie
  • *
  • Posts: 32
    • View Profile
Re: Loading charset
« Reply #7 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);

}

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Loading charset
« Reply #8 on: August 08, 2013, 08:58:37 pm »
Could you post the "game loop and all the other stuff" code?

lockandstrike

  • Newbie
  • *
  • Posts: 32
    • View Profile
Re: Loading charset
« Reply #9 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();

    }
  }
}
 

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Loading charset
« Reply #10 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.

G.

  • Hero Member
  • *****
  • Posts: 1590
    • View Profile
Re: Loading charset
« Reply #11 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.
« Last Edit: August 09, 2013, 11:13:02 am by G. »

Ivan

  • Newbie
  • *
  • Posts: 32
  • IT geek
    • View Profile
Re: Loading charset
« Reply #12 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);
 
  ....
 

lockandstrike

  • Newbie
  • *
  • Posts: 32
    • View Profile
Re: Loading charset
« Reply #13 on: August 09, 2013, 11:43:43 am »
Thanks Ivan. It worked. I can finally load all my textures right. Thanks alot.

G.

  • Hero Member
  • *****
  • Posts: 1590
    • View Profile
Re: [SOLVED]Loading charset
« Reply #14 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. :)

 

anything