Where should I store textures for a game?











up vote
0
down vote

favorite












I am currently creating a game in SFML using C++ and I'm wondering: what is good practise for a location for textures? Should I store it with my project? Or my executable? Or even in something like the Documents folder? What would be the most efficient when the game would theoretically be released, as it will not simply include the project but rather a compiled and build version of it?










share|improve this question






















  • You might want to ask this in Gave Development Exchange forum, you'll probably get better feedback there: gamedev.stackexchange.com
    – ihavenoidea
    Nov 10 at 16:26










  • @ihavenoidea good of you to redirect OP to the gamedev SE, but please it bears repeating that neither SO nor any other StackExchange site is a forum. They are question and answer sites. Forums imply that there are discussions to be had, but that kind of thing is specifically discouraged here.
    – dandan78
    Nov 10 at 16:44






  • 1




    It depends what OS you are installing it onto. Some build systems take care of that for you. As far as your code goes you could either make it a compile time macro set by the compiler or an environment variable (or both).
    – Galik
    Nov 10 at 16:46












  • Depends also on program size. If you hard code the textures (in your executable), you executable will take longer to load. You could store the textures in a file and load on demand.
    – Thomas Matthews
    Nov 10 at 17:32















up vote
0
down vote

favorite












I am currently creating a game in SFML using C++ and I'm wondering: what is good practise for a location for textures? Should I store it with my project? Or my executable? Or even in something like the Documents folder? What would be the most efficient when the game would theoretically be released, as it will not simply include the project but rather a compiled and build version of it?










share|improve this question






















  • You might want to ask this in Gave Development Exchange forum, you'll probably get better feedback there: gamedev.stackexchange.com
    – ihavenoidea
    Nov 10 at 16:26










  • @ihavenoidea good of you to redirect OP to the gamedev SE, but please it bears repeating that neither SO nor any other StackExchange site is a forum. They are question and answer sites. Forums imply that there are discussions to be had, but that kind of thing is specifically discouraged here.
    – dandan78
    Nov 10 at 16:44






  • 1




    It depends what OS you are installing it onto. Some build systems take care of that for you. As far as your code goes you could either make it a compile time macro set by the compiler or an environment variable (or both).
    – Galik
    Nov 10 at 16:46












  • Depends also on program size. If you hard code the textures (in your executable), you executable will take longer to load. You could store the textures in a file and load on demand.
    – Thomas Matthews
    Nov 10 at 17:32













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am currently creating a game in SFML using C++ and I'm wondering: what is good practise for a location for textures? Should I store it with my project? Or my executable? Or even in something like the Documents folder? What would be the most efficient when the game would theoretically be released, as it will not simply include the project but rather a compiled and build version of it?










share|improve this question













I am currently creating a game in SFML using C++ and I'm wondering: what is good practise for a location for textures? Should I store it with my project? Or my executable? Or even in something like the Documents folder? What would be the most efficient when the game would theoretically be released, as it will not simply include the project but rather a compiled and build version of it?







c++ sfml game-development






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 10 at 16:20









Lorago

193




193












  • You might want to ask this in Gave Development Exchange forum, you'll probably get better feedback there: gamedev.stackexchange.com
    – ihavenoidea
    Nov 10 at 16:26










  • @ihavenoidea good of you to redirect OP to the gamedev SE, but please it bears repeating that neither SO nor any other StackExchange site is a forum. They are question and answer sites. Forums imply that there are discussions to be had, but that kind of thing is specifically discouraged here.
    – dandan78
    Nov 10 at 16:44






  • 1




    It depends what OS you are installing it onto. Some build systems take care of that for you. As far as your code goes you could either make it a compile time macro set by the compiler or an environment variable (or both).
    – Galik
    Nov 10 at 16:46












  • Depends also on program size. If you hard code the textures (in your executable), you executable will take longer to load. You could store the textures in a file and load on demand.
    – Thomas Matthews
    Nov 10 at 17:32


















  • You might want to ask this in Gave Development Exchange forum, you'll probably get better feedback there: gamedev.stackexchange.com
    – ihavenoidea
    Nov 10 at 16:26










  • @ihavenoidea good of you to redirect OP to the gamedev SE, but please it bears repeating that neither SO nor any other StackExchange site is a forum. They are question and answer sites. Forums imply that there are discussions to be had, but that kind of thing is specifically discouraged here.
    – dandan78
    Nov 10 at 16:44






  • 1




    It depends what OS you are installing it onto. Some build systems take care of that for you. As far as your code goes you could either make it a compile time macro set by the compiler or an environment variable (or both).
    – Galik
    Nov 10 at 16:46












  • Depends also on program size. If you hard code the textures (in your executable), you executable will take longer to load. You could store the textures in a file and load on demand.
    – Thomas Matthews
    Nov 10 at 17:32
















You might want to ask this in Gave Development Exchange forum, you'll probably get better feedback there: gamedev.stackexchange.com
– ihavenoidea
Nov 10 at 16:26




You might want to ask this in Gave Development Exchange forum, you'll probably get better feedback there: gamedev.stackexchange.com
– ihavenoidea
Nov 10 at 16:26












@ihavenoidea good of you to redirect OP to the gamedev SE, but please it bears repeating that neither SO nor any other StackExchange site is a forum. They are question and answer sites. Forums imply that there are discussions to be had, but that kind of thing is specifically discouraged here.
– dandan78
Nov 10 at 16:44




@ihavenoidea good of you to redirect OP to the gamedev SE, but please it bears repeating that neither SO nor any other StackExchange site is a forum. They are question and answer sites. Forums imply that there are discussions to be had, but that kind of thing is specifically discouraged here.
– dandan78
Nov 10 at 16:44




1




1




It depends what OS you are installing it onto. Some build systems take care of that for you. As far as your code goes you could either make it a compile time macro set by the compiler or an environment variable (or both).
– Galik
Nov 10 at 16:46






It depends what OS you are installing it onto. Some build systems take care of that for you. As far as your code goes you could either make it a compile time macro set by the compiler or an environment variable (or both).
– Galik
Nov 10 at 16:46














Depends also on program size. If you hard code the textures (in your executable), you executable will take longer to load. You could store the textures in a file and load on demand.
– Thomas Matthews
Nov 10 at 17:32




Depends also on program size. If you hard code the textures (in your executable), you executable will take longer to load. You could store the textures in a file and load on demand.
– Thomas Matthews
Nov 10 at 17:32












1 Answer
1






active

oldest

votes

















up vote
0
down vote













Most common game releases have their textures inside a Media folder or similar.
Inside that folder are also placed sounds, music, and other content, tipically into separate folders.



They can't be part of the executable (as far as I know). More important is how do you manage those textures inside your code, it should be an efficient way.
I've added an explanation about how to do that, if you're interested.



TL DR



From my own experience making some small videogames, I found better to use a Resource Holder. This is a generic container for any heavy resource (textures, music, sounds or even fonts).



The main idea behind this is to have a map which relates a key (an ID) with a resource.
As you may want to store diferent kinds of resources, it's better to make a generic class.



A basic implementation:



template <typename Resource, typename Identifier>
class ResourceHolder
{
public:
void load(Identifier id, const std::string& filename){
// Create and load resource
std::unique_ptr<Resource> resource(new Resource());
if (!resource->loadFromFile(filename))
throw std::runtime_error("ResourceHolder::load - Failed to load " + filename);

// If loading successful, insert resource to map
insertResource(id, std::move(resource));
}

Resource& get(Identifier id){
auto found = mResourceMap.find(id);
assert(found != mResourceMap.end());

return *found->second;
}

const Resource& get(Identifier id) const {
auto found = mResourceMap.find(id);
assert(found != mResourceMap.end());

return *found->second;
}


protected:
void insertResource(Identifier id, std::unique_ptr<Resource> resource){
// Insert and check success
auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource)));
assert(inserted.second);
}


protected:
std::map<Identifier, std::unique_ptr<Resource>> mResourceMap;
};


I normally prefer to keep separate .hpp and .cpp, but I merged them to avoid a (even) longer post.



To keep things clean and useful, it's a good practice to have Resource Identifier header file, where you can declare types for your resource holders, and your resource identifiers too.



// Forward declaration of SFML classes
namespace sf
{
class Texture;
// If you need, you can use other SFML classes into your holders the same way
//class Font;
//class SoundBuffer;
}

namespace Textures
{
enum ID
{
TitleScreen,
LoadingScreen,
GameOverScreen,
Title,
Controls,
GUI,
TileMap,
Player,
Enemy,
Key,
PlayerMods
};
}

// Forward declaration and a few type definitions
template <typename Resource, typename Identifier>
class ResourceHolder;

typedef ResourceHolder<sf::Texture, Textures::ID> TextureHolder;
//typedef ResourceHolder<sf::Font, Fonts::ID> FontHolder;
//typedef ResourceHolder<sf::SoundBuffer, Sounds::ID> SoundHolder;


As an example of use, if you have something like a Game class (a class that will be loaded as long as your application is running), you can do like this:



class Game {
public:
Game() :
_window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Game")
{
// EXAMPLES
//_fonts.load(Fonts::Main, FONTS_FOLDER + "font.ttf");
//_musics.load(Musics::Game, MUSIC_FOLDER + "main.ogg");
//_musics.get(Musics::Game).setLoop(true);
//_sounds.load(Sounds::Key, SOUNDS_FOLDER + "key.wav");


_textures.load(Textures::TitleScreen, TEXTURES_FOLDER + "titlescreen.png");

// More code ...
}

void run(){
// Your game loop: process inputs, update and render until you close
}
private:
void update(sf::Time dt){
// ...
}

void processInput(){
// ...
}

void render(){
_window.clear(sf::Color::Black);

// Here you can use your resources to draw
sf::Sprite sp(_textures.get(Textures::TitleScreen));
_window.draw(sp);

_window.display();
}

sf::RenderWindow _window;
TextureHolder _textures;
//FontHolder _fonts;
//SoundHolder _sounds;
};


The key with this approach is to have your holders inside an always loaded class, and pass your holders as pointers or references. Another good way to do that is to have a Context class, which holds and group those pointers into only one class, and use that context as a parameter (even by copy, because it's a light class) of all your classes that will need a resource:



struct Context
{
Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, MusicHolder& musics, SoundHolder& sounds);

sf::RenderWindow* window;
TextureHolder* textures;
FontHolder* fonts;
MusicHolder* musics;
SoundHolder* sounds;
};


You can find more info about this here: SFML Game Development, source of this implementation.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53240918%2fwhere-should-i-store-textures-for-a-game%23new-answer', 'question_page');
    }
    );

    Post as a guest
































    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    Most common game releases have their textures inside a Media folder or similar.
    Inside that folder are also placed sounds, music, and other content, tipically into separate folders.



    They can't be part of the executable (as far as I know). More important is how do you manage those textures inside your code, it should be an efficient way.
    I've added an explanation about how to do that, if you're interested.



    TL DR



    From my own experience making some small videogames, I found better to use a Resource Holder. This is a generic container for any heavy resource (textures, music, sounds or even fonts).



    The main idea behind this is to have a map which relates a key (an ID) with a resource.
    As you may want to store diferent kinds of resources, it's better to make a generic class.



    A basic implementation:



    template <typename Resource, typename Identifier>
    class ResourceHolder
    {
    public:
    void load(Identifier id, const std::string& filename){
    // Create and load resource
    std::unique_ptr<Resource> resource(new Resource());
    if (!resource->loadFromFile(filename))
    throw std::runtime_error("ResourceHolder::load - Failed to load " + filename);

    // If loading successful, insert resource to map
    insertResource(id, std::move(resource));
    }

    Resource& get(Identifier id){
    auto found = mResourceMap.find(id);
    assert(found != mResourceMap.end());

    return *found->second;
    }

    const Resource& get(Identifier id) const {
    auto found = mResourceMap.find(id);
    assert(found != mResourceMap.end());

    return *found->second;
    }


    protected:
    void insertResource(Identifier id, std::unique_ptr<Resource> resource){
    // Insert and check success
    auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource)));
    assert(inserted.second);
    }


    protected:
    std::map<Identifier, std::unique_ptr<Resource>> mResourceMap;
    };


    I normally prefer to keep separate .hpp and .cpp, but I merged them to avoid a (even) longer post.



    To keep things clean and useful, it's a good practice to have Resource Identifier header file, where you can declare types for your resource holders, and your resource identifiers too.



    // Forward declaration of SFML classes
    namespace sf
    {
    class Texture;
    // If you need, you can use other SFML classes into your holders the same way
    //class Font;
    //class SoundBuffer;
    }

    namespace Textures
    {
    enum ID
    {
    TitleScreen,
    LoadingScreen,
    GameOverScreen,
    Title,
    Controls,
    GUI,
    TileMap,
    Player,
    Enemy,
    Key,
    PlayerMods
    };
    }

    // Forward declaration and a few type definitions
    template <typename Resource, typename Identifier>
    class ResourceHolder;

    typedef ResourceHolder<sf::Texture, Textures::ID> TextureHolder;
    //typedef ResourceHolder<sf::Font, Fonts::ID> FontHolder;
    //typedef ResourceHolder<sf::SoundBuffer, Sounds::ID> SoundHolder;


    As an example of use, if you have something like a Game class (a class that will be loaded as long as your application is running), you can do like this:



    class Game {
    public:
    Game() :
    _window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Game")
    {
    // EXAMPLES
    //_fonts.load(Fonts::Main, FONTS_FOLDER + "font.ttf");
    //_musics.load(Musics::Game, MUSIC_FOLDER + "main.ogg");
    //_musics.get(Musics::Game).setLoop(true);
    //_sounds.load(Sounds::Key, SOUNDS_FOLDER + "key.wav");


    _textures.load(Textures::TitleScreen, TEXTURES_FOLDER + "titlescreen.png");

    // More code ...
    }

    void run(){
    // Your game loop: process inputs, update and render until you close
    }
    private:
    void update(sf::Time dt){
    // ...
    }

    void processInput(){
    // ...
    }

    void render(){
    _window.clear(sf::Color::Black);

    // Here you can use your resources to draw
    sf::Sprite sp(_textures.get(Textures::TitleScreen));
    _window.draw(sp);

    _window.display();
    }

    sf::RenderWindow _window;
    TextureHolder _textures;
    //FontHolder _fonts;
    //SoundHolder _sounds;
    };


    The key with this approach is to have your holders inside an always loaded class, and pass your holders as pointers or references. Another good way to do that is to have a Context class, which holds and group those pointers into only one class, and use that context as a parameter (even by copy, because it's a light class) of all your classes that will need a resource:



    struct Context
    {
    Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, MusicHolder& musics, SoundHolder& sounds);

    sf::RenderWindow* window;
    TextureHolder* textures;
    FontHolder* fonts;
    MusicHolder* musics;
    SoundHolder* sounds;
    };


    You can find more info about this here: SFML Game Development, source of this implementation.






    share|improve this answer



























      up vote
      0
      down vote













      Most common game releases have their textures inside a Media folder or similar.
      Inside that folder are also placed sounds, music, and other content, tipically into separate folders.



      They can't be part of the executable (as far as I know). More important is how do you manage those textures inside your code, it should be an efficient way.
      I've added an explanation about how to do that, if you're interested.



      TL DR



      From my own experience making some small videogames, I found better to use a Resource Holder. This is a generic container for any heavy resource (textures, music, sounds or even fonts).



      The main idea behind this is to have a map which relates a key (an ID) with a resource.
      As you may want to store diferent kinds of resources, it's better to make a generic class.



      A basic implementation:



      template <typename Resource, typename Identifier>
      class ResourceHolder
      {
      public:
      void load(Identifier id, const std::string& filename){
      // Create and load resource
      std::unique_ptr<Resource> resource(new Resource());
      if (!resource->loadFromFile(filename))
      throw std::runtime_error("ResourceHolder::load - Failed to load " + filename);

      // If loading successful, insert resource to map
      insertResource(id, std::move(resource));
      }

      Resource& get(Identifier id){
      auto found = mResourceMap.find(id);
      assert(found != mResourceMap.end());

      return *found->second;
      }

      const Resource& get(Identifier id) const {
      auto found = mResourceMap.find(id);
      assert(found != mResourceMap.end());

      return *found->second;
      }


      protected:
      void insertResource(Identifier id, std::unique_ptr<Resource> resource){
      // Insert and check success
      auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource)));
      assert(inserted.second);
      }


      protected:
      std::map<Identifier, std::unique_ptr<Resource>> mResourceMap;
      };


      I normally prefer to keep separate .hpp and .cpp, but I merged them to avoid a (even) longer post.



      To keep things clean and useful, it's a good practice to have Resource Identifier header file, where you can declare types for your resource holders, and your resource identifiers too.



      // Forward declaration of SFML classes
      namespace sf
      {
      class Texture;
      // If you need, you can use other SFML classes into your holders the same way
      //class Font;
      //class SoundBuffer;
      }

      namespace Textures
      {
      enum ID
      {
      TitleScreen,
      LoadingScreen,
      GameOverScreen,
      Title,
      Controls,
      GUI,
      TileMap,
      Player,
      Enemy,
      Key,
      PlayerMods
      };
      }

      // Forward declaration and a few type definitions
      template <typename Resource, typename Identifier>
      class ResourceHolder;

      typedef ResourceHolder<sf::Texture, Textures::ID> TextureHolder;
      //typedef ResourceHolder<sf::Font, Fonts::ID> FontHolder;
      //typedef ResourceHolder<sf::SoundBuffer, Sounds::ID> SoundHolder;


      As an example of use, if you have something like a Game class (a class that will be loaded as long as your application is running), you can do like this:



      class Game {
      public:
      Game() :
      _window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Game")
      {
      // EXAMPLES
      //_fonts.load(Fonts::Main, FONTS_FOLDER + "font.ttf");
      //_musics.load(Musics::Game, MUSIC_FOLDER + "main.ogg");
      //_musics.get(Musics::Game).setLoop(true);
      //_sounds.load(Sounds::Key, SOUNDS_FOLDER + "key.wav");


      _textures.load(Textures::TitleScreen, TEXTURES_FOLDER + "titlescreen.png");

      // More code ...
      }

      void run(){
      // Your game loop: process inputs, update and render until you close
      }
      private:
      void update(sf::Time dt){
      // ...
      }

      void processInput(){
      // ...
      }

      void render(){
      _window.clear(sf::Color::Black);

      // Here you can use your resources to draw
      sf::Sprite sp(_textures.get(Textures::TitleScreen));
      _window.draw(sp);

      _window.display();
      }

      sf::RenderWindow _window;
      TextureHolder _textures;
      //FontHolder _fonts;
      //SoundHolder _sounds;
      };


      The key with this approach is to have your holders inside an always loaded class, and pass your holders as pointers or references. Another good way to do that is to have a Context class, which holds and group those pointers into only one class, and use that context as a parameter (even by copy, because it's a light class) of all your classes that will need a resource:



      struct Context
      {
      Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, MusicHolder& musics, SoundHolder& sounds);

      sf::RenderWindow* window;
      TextureHolder* textures;
      FontHolder* fonts;
      MusicHolder* musics;
      SoundHolder* sounds;
      };


      You can find more info about this here: SFML Game Development, source of this implementation.






      share|improve this answer

























        up vote
        0
        down vote










        up vote
        0
        down vote









        Most common game releases have their textures inside a Media folder or similar.
        Inside that folder are also placed sounds, music, and other content, tipically into separate folders.



        They can't be part of the executable (as far as I know). More important is how do you manage those textures inside your code, it should be an efficient way.
        I've added an explanation about how to do that, if you're interested.



        TL DR



        From my own experience making some small videogames, I found better to use a Resource Holder. This is a generic container for any heavy resource (textures, music, sounds or even fonts).



        The main idea behind this is to have a map which relates a key (an ID) with a resource.
        As you may want to store diferent kinds of resources, it's better to make a generic class.



        A basic implementation:



        template <typename Resource, typename Identifier>
        class ResourceHolder
        {
        public:
        void load(Identifier id, const std::string& filename){
        // Create and load resource
        std::unique_ptr<Resource> resource(new Resource());
        if (!resource->loadFromFile(filename))
        throw std::runtime_error("ResourceHolder::load - Failed to load " + filename);

        // If loading successful, insert resource to map
        insertResource(id, std::move(resource));
        }

        Resource& get(Identifier id){
        auto found = mResourceMap.find(id);
        assert(found != mResourceMap.end());

        return *found->second;
        }

        const Resource& get(Identifier id) const {
        auto found = mResourceMap.find(id);
        assert(found != mResourceMap.end());

        return *found->second;
        }


        protected:
        void insertResource(Identifier id, std::unique_ptr<Resource> resource){
        // Insert and check success
        auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource)));
        assert(inserted.second);
        }


        protected:
        std::map<Identifier, std::unique_ptr<Resource>> mResourceMap;
        };


        I normally prefer to keep separate .hpp and .cpp, but I merged them to avoid a (even) longer post.



        To keep things clean and useful, it's a good practice to have Resource Identifier header file, where you can declare types for your resource holders, and your resource identifiers too.



        // Forward declaration of SFML classes
        namespace sf
        {
        class Texture;
        // If you need, you can use other SFML classes into your holders the same way
        //class Font;
        //class SoundBuffer;
        }

        namespace Textures
        {
        enum ID
        {
        TitleScreen,
        LoadingScreen,
        GameOverScreen,
        Title,
        Controls,
        GUI,
        TileMap,
        Player,
        Enemy,
        Key,
        PlayerMods
        };
        }

        // Forward declaration and a few type definitions
        template <typename Resource, typename Identifier>
        class ResourceHolder;

        typedef ResourceHolder<sf::Texture, Textures::ID> TextureHolder;
        //typedef ResourceHolder<sf::Font, Fonts::ID> FontHolder;
        //typedef ResourceHolder<sf::SoundBuffer, Sounds::ID> SoundHolder;


        As an example of use, if you have something like a Game class (a class that will be loaded as long as your application is running), you can do like this:



        class Game {
        public:
        Game() :
        _window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Game")
        {
        // EXAMPLES
        //_fonts.load(Fonts::Main, FONTS_FOLDER + "font.ttf");
        //_musics.load(Musics::Game, MUSIC_FOLDER + "main.ogg");
        //_musics.get(Musics::Game).setLoop(true);
        //_sounds.load(Sounds::Key, SOUNDS_FOLDER + "key.wav");


        _textures.load(Textures::TitleScreen, TEXTURES_FOLDER + "titlescreen.png");

        // More code ...
        }

        void run(){
        // Your game loop: process inputs, update and render until you close
        }
        private:
        void update(sf::Time dt){
        // ...
        }

        void processInput(){
        // ...
        }

        void render(){
        _window.clear(sf::Color::Black);

        // Here you can use your resources to draw
        sf::Sprite sp(_textures.get(Textures::TitleScreen));
        _window.draw(sp);

        _window.display();
        }

        sf::RenderWindow _window;
        TextureHolder _textures;
        //FontHolder _fonts;
        //SoundHolder _sounds;
        };


        The key with this approach is to have your holders inside an always loaded class, and pass your holders as pointers or references. Another good way to do that is to have a Context class, which holds and group those pointers into only one class, and use that context as a parameter (even by copy, because it's a light class) of all your classes that will need a resource:



        struct Context
        {
        Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, MusicHolder& musics, SoundHolder& sounds);

        sf::RenderWindow* window;
        TextureHolder* textures;
        FontHolder* fonts;
        MusicHolder* musics;
        SoundHolder* sounds;
        };


        You can find more info about this here: SFML Game Development, source of this implementation.






        share|improve this answer














        Most common game releases have their textures inside a Media folder or similar.
        Inside that folder are also placed sounds, music, and other content, tipically into separate folders.



        They can't be part of the executable (as far as I know). More important is how do you manage those textures inside your code, it should be an efficient way.
        I've added an explanation about how to do that, if you're interested.



        TL DR



        From my own experience making some small videogames, I found better to use a Resource Holder. This is a generic container for any heavy resource (textures, music, sounds or even fonts).



        The main idea behind this is to have a map which relates a key (an ID) with a resource.
        As you may want to store diferent kinds of resources, it's better to make a generic class.



        A basic implementation:



        template <typename Resource, typename Identifier>
        class ResourceHolder
        {
        public:
        void load(Identifier id, const std::string& filename){
        // Create and load resource
        std::unique_ptr<Resource> resource(new Resource());
        if (!resource->loadFromFile(filename))
        throw std::runtime_error("ResourceHolder::load - Failed to load " + filename);

        // If loading successful, insert resource to map
        insertResource(id, std::move(resource));
        }

        Resource& get(Identifier id){
        auto found = mResourceMap.find(id);
        assert(found != mResourceMap.end());

        return *found->second;
        }

        const Resource& get(Identifier id) const {
        auto found = mResourceMap.find(id);
        assert(found != mResourceMap.end());

        return *found->second;
        }


        protected:
        void insertResource(Identifier id, std::unique_ptr<Resource> resource){
        // Insert and check success
        auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource)));
        assert(inserted.second);
        }


        protected:
        std::map<Identifier, std::unique_ptr<Resource>> mResourceMap;
        };


        I normally prefer to keep separate .hpp and .cpp, but I merged them to avoid a (even) longer post.



        To keep things clean and useful, it's a good practice to have Resource Identifier header file, where you can declare types for your resource holders, and your resource identifiers too.



        // Forward declaration of SFML classes
        namespace sf
        {
        class Texture;
        // If you need, you can use other SFML classes into your holders the same way
        //class Font;
        //class SoundBuffer;
        }

        namespace Textures
        {
        enum ID
        {
        TitleScreen,
        LoadingScreen,
        GameOverScreen,
        Title,
        Controls,
        GUI,
        TileMap,
        Player,
        Enemy,
        Key,
        PlayerMods
        };
        }

        // Forward declaration and a few type definitions
        template <typename Resource, typename Identifier>
        class ResourceHolder;

        typedef ResourceHolder<sf::Texture, Textures::ID> TextureHolder;
        //typedef ResourceHolder<sf::Font, Fonts::ID> FontHolder;
        //typedef ResourceHolder<sf::SoundBuffer, Sounds::ID> SoundHolder;


        As an example of use, if you have something like a Game class (a class that will be loaded as long as your application is running), you can do like this:



        class Game {
        public:
        Game() :
        _window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Game")
        {
        // EXAMPLES
        //_fonts.load(Fonts::Main, FONTS_FOLDER + "font.ttf");
        //_musics.load(Musics::Game, MUSIC_FOLDER + "main.ogg");
        //_musics.get(Musics::Game).setLoop(true);
        //_sounds.load(Sounds::Key, SOUNDS_FOLDER + "key.wav");


        _textures.load(Textures::TitleScreen, TEXTURES_FOLDER + "titlescreen.png");

        // More code ...
        }

        void run(){
        // Your game loop: process inputs, update and render until you close
        }
        private:
        void update(sf::Time dt){
        // ...
        }

        void processInput(){
        // ...
        }

        void render(){
        _window.clear(sf::Color::Black);

        // Here you can use your resources to draw
        sf::Sprite sp(_textures.get(Textures::TitleScreen));
        _window.draw(sp);

        _window.display();
        }

        sf::RenderWindow _window;
        TextureHolder _textures;
        //FontHolder _fonts;
        //SoundHolder _sounds;
        };


        The key with this approach is to have your holders inside an always loaded class, and pass your holders as pointers or references. Another good way to do that is to have a Context class, which holds and group those pointers into only one class, and use that context as a parameter (even by copy, because it's a light class) of all your classes that will need a resource:



        struct Context
        {
        Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, MusicHolder& musics, SoundHolder& sounds);

        sf::RenderWindow* window;
        TextureHolder* textures;
        FontHolder* fonts;
        MusicHolder* musics;
        SoundHolder* sounds;
        };


        You can find more info about this here: SFML Game Development, source of this implementation.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 14 hours ago

























        answered yesterday









        alseether

        1,23211229




        1,23211229






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53240918%2fwhere-should-i-store-textures-for-a-game%23new-answer', 'question_page');
            }
            );

            Post as a guest




















































































            Popular posts from this blog

            Xamarin.iOS Cant Deploy on Iphone

            Glorious Revolution

            Dulmage-Mendelsohn matrix decomposition in Python