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

Author Topic: I can't load my game resources into SFML with CMake  (Read 2954 times)

0 Members and 1 Guest are viewing this topic.

MrAlce

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
I can't load my game resources into SFML with CMake
« on: December 24, 2021, 07:01:34 pm »
I am programming a little game in C ++ using Visual Studio Code with CMake as the Build System. So far there hadn't been any problem with accessing resources, but since I decided to tidy up my project by organizing it in directories, my GetTexture, GetSoundBuffer and GetFont functions are unable to load images from the Resources folder.

Obviously I know that when saving the files in different directories, I had to update the paths. So what at first was "Resources / image.png" became "../../../Resources/image.png", (which did work for all #include directives) but when I run the game I only see the black screen and console showing me messages like Failed to load image "../../../Resources/image.png". Reason: Unable to open file.

I've tried over and over again to rearrange the project but every time I compile this happens. I don't know much about CMake and I don't know if the problem is with my CMakeLists.txt file or with my previously mentioned functions, which I doubt as they worked perfectly before.

GetTexture:

sf::Texture& Game::GetTexture(std::string _fileName)
{    
    auto iter = textures.find(_fileName);
    if (iter != textures.end())
    {        
        return *iter->second;
    }      
   
    TexturePtr texture = std::make_shared<sf::Texture>();
    texture->loadFromFile(_fileName);
    textures[_fileName] = texture;
   
    return *texture;
}
 
GetSoundBuffer:

sf::SoundBuffer& Game::GetSoundBuffer(std::string _fileName)
{
     auto iter = sounds.find(_fileName);
     if (iter != sounds.end())
     {
         return *iter->second;
     }
     
     SoundBufferPtr sound = std::make_shared<sf::SoundBuffer>();
     sound->loadFromFile(_fileName);      sounds[_fileName] = sound;
     
    return *sound;
}

GetFont:

sf::Font& Game::GetFont(std::string _fileName)
{    
    auto iter = fonts.find(_fileName);
    if (iter != fonts.end())
    {        
        return *iter->second;
    }

    FontPtr font = std::make_shared<sf::Font>();
    font->loadFromFile(_fileName);
    fonts[_fileName] = font;
     
    return *font;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.18)
set(PROJECT_NAME "MyGame")
project(MyGame)

set(SFML_DIR "${CMAKE_CURRENT_LIST_DIR}/libs/SFML-2.5.1/lib/cmake/SFML")

file(GLOB ALL_REQUIRED_DLL "libs/required_dlls/*.dll")
file(COPY ${ALL_REQUIRED_DLL} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

set(CMAKE_CXX_STANDARD 17)

set(SOURCE_FILES
    main.cpp
    ...
  ${RES_FILES})
 

add_executable(${PROJECT_NAME} ${SOURCE_FILES})

find_package(SFML 2.5.1 COMPONENTS system window graphics network audio REQUIRED)
target_link_libraries(${PROJECT_NAME} sfml-audio sfml-graphics sfml-window sfml-system)

The organization of the project is as follows:

Build:     
    (Cmake build stuff) 

Engine:
    (All engine codes, no problem here)

Scenes:
      Scene1:
          include:
              (All .h files)
          src:
              (All .cpp files, here is where i call GetTexture, GetSoundBuffer 
              and GetFont)

Resources:
      (All the images, sounds and fonts) 

CMakeLists.txt
main.cpp 


To all this, it is also worth mentioning that I am using Linux.

metal_in_my_veins

  • Newbie
  • *
  • Posts: 10
    • View Profile
    • Email
Re: I can't load my game resources into SFML with CMake
« Reply #1 on: January 01, 2022, 09:23:37 pm »
If I understand you correctly, SFML is unable to access the resources in your program. I have a workaround in mind. Although I am not sure if it would work or not. Just try it and let me know.

Suppose you have all your resources in a folder called 'media' which is situated in cmake source path. Then simply add this line in your CMakeLists.txt.
.....
.....
set(CMAKE_CXX_STANDARD 17)
# add this line
include_directories(${CMAKE_SOURCE_DIR}/media)
.....
.....
 

Now you should be able to access the resources from anywhere of your programs if you have done the other cmake parts correctly. For example you should be able to load your resources like this:
someTexture.loadFromFile("media/Graphics/background.png");
 

Tell me if it worked.
(But how come you are using linux? I see you linking dlls)
« Last Edit: January 01, 2022, 09:26:56 pm by metal_in_my_veins »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: I can't load my game resources into SFML with CMake
« Reply #2 on: January 03, 2022, 01:13:09 pm »
Resource loading is completely independent of your build system. The only thing that does matter with relative paths, is what the working directory is set to when executing the application, that will ultimately be the "root".

The simplest thing is to use the install() instructions in CMake and put the resource directory and executable next to each other, than always build the install target. That way both executable and resources are copied to the correct location, now all you need to make sure is that when you run the application, that the working directory is set to the same location as the executable that is being executed.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/