androidc++imagetexturessdl-3

SDL3 Texture Create returns always NULL


I have a problem in my c++ SDL3 android project: Every time I try to create a texture it returns NULL, and if I call SDL_GetError() it says absolutely nothing. And I tried everything:

//  ATTEMPT 1
SDL_Surface* surface = SDL_LoadBMP("center_arrow.bmp");
if (surface == NULL)
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load surface: %s\n", SDL_GetError());
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
if (texture == NULL)
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load texture: %s\n", SDL_GetError());

Outputs:

Could not load texture:

(Which means that the Surface was created Successfully, but SDL_CreateTextureFromSurface() returned NULL without any explanation from SDL_GetError())

So I installed SDL3_Image.

//  ATTEMPT 2
SDL_Texture* texture = IMG_LoadTexture(renderer, "center_arrow.png");
if (texture == NULL)
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load texture: %s\n", SDL_GetError());

Outputs:

Could not load texture:

(IMG_LoadTexture(), a function from a completely new library, give the exactly same error, it returns NULL without any explanation from SDL_GetError(). I used a new file format too, PNG instead of BMP, but same results)

So I tried other functions of the IMG library.

//  ATTEMPT 3
SDL_Surface* surface = IMG_Load("center_arrow.png");
if (surface == NULL)
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load surface: %s\n", SDL_GetError());
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
if (texture == NULL)
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load texture: %s\n", SDL_GetError());

Outputs:

Could not load texture:

(Which means again, surface created successfully, but texture NULL);

So I tried converting the PixelFormat of the surface into the PixelFormat of the window.

//  ATTEMPT 4
SDL_PixelFormat windowPixelFormat = SDL_GetWindowPixelFormat(window);

SDL_Surface* surface = SDL_LoadBMP("lettuce.bmp");
if (surface == NULL)
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load surface: %s\n", SDL_GetError());
else
    SDL_Log("Surface pixel format: %s", SDL_GetPixelFormatName(surface->format));

SDL_Surface* converted_surface = SDL_ConvertSurface(surface, windowPixelFormat);
if (converted_surface == NULL)
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not convert surface: %s\n", SDL_GetError());
else
    SDL_Log("Converted surface pixel format: %s", SDL_GetPixelFormatName(converted_surface->format));

SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, converted_surface);
if (texture == NULL)
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load texture: %s\n", SDL_GetError());

Outputs:

Surface pixel format: SDL_PIXELFORMAT_ARGB8888

Converted surface pixel format: SDL_PIXELFORMAT_RGB565

Could not load texture:

(Again... texture always NULL. I'm becoming desperate)

My full code is very simple, it only consists of one file.

#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3_image/SDL_image.h>

int main(int argc, char *argv[]) {
    (void)argc;
    (void)argv;

    if (!SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init failed (%s)", SDL_GetError());
        SDL_Quit();
        return 1;
    }

    if (!IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG)) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "IMG_Init failed.");
        SDL_Quit();
        return 1;
    }

    SDL_DisplayID* displayID = SDL_GetDisplays(NULL);
    const SDL_DisplayMode* screen = SDL_GetCurrentDisplayMode(*displayID);
    if (screen == NULL)
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GetCurrentDisplayMode failed (%s)", SDL_GetError());
    else
        SDL_Log("Screen resolution: %dx%d", screen->w, screen->h);

    SDL_Window* window = SDL_CreateWindow("Game", screen->w, screen->h, SDL_WINDOW_VULKAN | SDL_WINDOW_FULLSCREEN);
    if (window == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create window: %s\n", SDL_GetError());
    }

    SDL_Renderer* renderer = SDL_CreateRenderer(window, NULL);
    if (renderer == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create renderer: %s\n", SDL_GetError());
    }

    //  ATTEMPT 2
    SDL_Texture* texture = IMG_LoadTexture(renderer, "center_arrow.png");
    if (texture == NULL)
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load texture: %s\n", SDL_GetError());

    SDL_Quit();
    IMG_Quit();
    return 0;
}

(I left only attempt 2 here, but with the other attempts it is completely analogous)

Outputs

Android Log filtered to show only my logs)

Full android log without filters (it's the same with all the other attempts too)

Other things I tried

Finally, I added a few lines in my code to read the SDL_Properties of window and renderer. So I read the pixel format of the Window, and then all the pixel formats supported by the Renderer, and found out that they don't match (in all the 3 devices):

Pixel formats of window and of renderer

I have no idea if this is causing the problem, but even if it was, I don't know what to do about it. I tried forcibly adding the format of the window into the properties of the renderer (into the pixel formats supported by the renderer), but SAME ERROR, texture NULL.

I'm starting to think that in SDL3 it's currently impossible to add an image, at least in android, I don't know what else to do.


Solution

  • It was an error of SDL 3.1.2 . They fixed it in SDL 3.1.3