Search code examples
csdlsdl-2

Why am I failing to initialize SDL_image?


This is an updated post. Someone asked me to do a minimal reproducible example, which did help a lot. This program opens a window, but does not display a PNG image as I would like it to do.

The compiler gives me no errors, however my error message for SDL_Init does.

What could be the reason that I am failing to initialize SDL_Image?

// std
#include <stdio.h>

// sdl
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

int main (int argc, char* argv[])
{
    // ----- Initialize SDL
    if (SDL_Init(SDL_INIT_VIDEO) != 0)
    {
        fprintf(stderr, "SDL could not initialize\n");
        return 1;
    }
    if (IMG_Init(IMG_INIT_PNG) != 0)
    {
        fprintf(stderr, "SDL_image could not initialize\n");
        /********
        I GET THIS ERROR
        ********/
    }

    // ----- Create window
    SDL_Window* window = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED,
                                                    SDL_WINDOWPOS_CENTERED,
                                                    800,
                                                    600, 
                                                    0);
    if (!window)
    {
        fprintf(stderr, "Error creating window.\n");
        return 2;
    }

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    SDL_Surface *image_surface = NULL;
    image_surface = IMG_Load("button_randomize.png");
    if(image_surface == NULL)
    {
        printf("Cannot find image\n"); // This line is not executed
        SDL_Quit();
    }
    SDL_Texture *image_texture = SDL_CreateTextureFromSurface(renderer, image_surface);
    SDL_FreeSurface(image_surface);

    // ----- Main loop
    int quit = 0;
    while (quit == 0)
    {
        SDL_Event windowEvent;
        while (SDL_PollEvent(&windowEvent))
        {
            if (windowEvent.type == SDL_QUIT)
            {
                quit = 1;
                break;
            }
        }

        SDL_Rect image_rect = {50, 50, 120, 32};
        SDL_RenderCopy(renderer, image_texture, NULL, &image_rect);
    }

    // ----- Clean up
    IMG_Quit();
    SDL_Quit();
    return 0;
}

Output:

SDL_image could not initialize

build command:

gcc -std=c11 -Wall -o obj/main.o -c src/main.c
gcc -std=c11 -Wall -o my_program obj/main.o -lSDL2 -lGL -lGLEW -lm -lSDL2_image

I have tried changing the SDL_Init flags. I even tried to change the IMG_Init flag to IMG_INIT_JPG (and testing with a .jpg image of course), but no luck.


Solution

  • There are two issues in this example:

    • IMG_Init() returns a bitmask of all the currently initted image loaders instead of 0 on success (this is why you get the error message)
    • You do not call SDL_RenderPresent() after drawing on the renderer (this is why you can't see anything)

    Here is an example on how to init SDL_Image from the SDL2_image documentation:

    // load support for the JPG and PNG image formats
    int flags = IMG_INIT_JPG | IMG_INIT_PNG;
    int initted = IMG_Init(flags);
    if ((initted & flags) != flags) {
        printf("IMG_Init: Failed to init required jpg and png support!\n");
        printf("IMG_Init: %s\n", IMG_GetError());
        // handle error
    }
    

    And to make the image visible add this to the end of the loop:

    SDL_RenderPresent(renderer);