c++linuxsdlclionsdl-image

SDL_image Can't load .png file with IMG_LoadTexture()


While trying to load a .png file with IMG_LoadTexture(renderer, "idle.png") SDL_GetError() says: "Couldn't open idle.png" There are no compiler errors, just a black window appears.

This is my main.cpp

#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>

int main(int argc,  char** argv) {
    SDL_Event event;
    SDL_Renderer *renderer = NULL;
    SDL_Texture *texture = NULL;
    SDL_Window *window = NULL;

    SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
    SDL_CreateWindowAndRenderer(
            800, 600,
            0, &window, &renderer
    );
    IMG_Init(IMG_INIT_PNG);
    texture = IMG_LoadTexture(renderer, "idle.png");
    std::cout << SDL_GetError();

    while (1) {
        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);
        if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
            break;
    }
    SDL_DestroyTexture(texture);
    IMG_Quit();
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return EXIT_SUCCESS;
}

But I guess the problem is the way I link the library. I installed sdl2, sdl2_image and libpng.

CMakeLists.txt:

cmake_minimum_required(VERSION 3.12)
project(untitled)

set(CMAKE_CXX_STANDARD 17)

add_executable(untitled main.cpp)

INCLUDE(FindPkgConfig)

PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)

INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(untitled ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES})

Solution

  • You are loading the image from the current working directory (CWD) of your application. That is not necessarily the same directory as your executable is in (it depends on how it is launched), which you seem to assume.

    3 easy ways to fix:

    1. change the cwd at runtime to where the file is and load as you do now.
    2. provide an absolute path to the file when loading, so cwd is irrelevant.
    3. obtain the path to the executable at runtime and then construct a path to the file relative to where the executable is. (best option in my opinion since it's robust against moving your project around/installing to a different location).