c++sdl-2sdl-image

SDL2_image rendering - Images render properly only when source SDL_Rect's properties are printed


My C++/SDL2 program uses a Sprites class with a std::map of pointers to SDL_Textures and member functions for loading and rendering images, however when the program ran none of the loaded images showed up in the window.

I've found that the Sprites instance is given a correct pointer to the renderer and IMG_LoadTexture did not return 0. The renderer is also working properly since primitives like SDL_RenderDrawLine are drawn just fine.

Interestingly when I wanted to check if SDL_QueryTexture gave correct dimensions by printing the source rectangle's width and height, the program rendered the images properly. The printed dimensions were also correct, and trying to print the x and y fixed it too.

Why does this happen?

Here's the two important member functions in the Sprites class.

void Sprites::load(std::string id, std::string filename, int length) {
    SDL_Texture* tex = IMG_LoadTexture(renderer, filename.c_str());
    if (tex == 0) {
        printf("Texture %s could not be loaded\n", filename.c_str());
    }

    sprmap[id] = tex;
    lengthmap[id] = length;
    printf("%s should be loaded now\n", id.c_str());
}

void Sprites::render(std::string id, float x, float y, int frame) {
    SDL_Rect src;
    SDL_Rect dest;
    SDL_QueryTexture(sprmap[id], NULL, NULL, &src.w, &src.h);
    src.w /= lengthmap[id];
    printf("src x: %s, src y %s\n", std::to_string(src.x).c_str(), std::to_string(src.y).c_str()); 
    //Images do not render when above line is omitted
    src.x = frame*src.w;
    dest.x = x;
    dest.y = y;
    dest.w = src.w;
    dest.h = src.h;
    SDL_RenderCopy(renderer, sprmap[id], &src, &dest);
}

Solution

  • Your SDL_Rect is not correctly initialised. Printing "fixes" it, but only by chance.

    Your SDL_QueryTexture allows you to initialise w and h, but x and y have completely random values. As to why EXACTLY printing the values fixes things is beyond me, but I suspect that the random values don't go well with SDL_RenderCopy (especially negative values).

    If you give proper values to x and y, your problem should go away.

    If you want to read more about how variables are initialised this SO post should be a good place to start.

    An alternative could be zero initialisation to make sure your structs always have a default value of 0. The simplest way should be like this : SDL_Rect src{};