SDL_BlitSurface doesn't display the surface


#1

Hello,

I’ve written a small program (actual Archlinux on x86_64 with SDL2 v. 2.0.5). Here is the code in abbreviated form:

if (SDL_Init(SDL_INIT_EVERYTHING))
{
    SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Could not initialize SDL: %s\n", SDL_GetError());
    return(ERROR);
}
if ((mainWindow = SDL_CreateWindow(basename(argv[0]),
                               SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                               320, 240,
                               SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL)) == NULL)
{
    SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Could not create window: %s\n", SDL_GetError());
    close_display();
    return(ERROR);
}
mainRenderer = SDL_CreateRenderer(mainWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
mainSurface  = SDL_GetWindowSurface(mainWindow);

imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
    SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Could not initialize SDL_image: %s\n", IMG_GetError());
    close_display();
    return(ERROR);
}

if ((gImage = IMG_Load("my_bg.png")) ==NULL)
{
    SDL_LogError(SDL_LOG_CATEGORY_ERROR,
                 "Unable to load image %s!\nSDL_image Error: %s\n",
                 basename(filename), IMG_GetError());
    return(NULL);
}
if ((frameSurface = SDL_ConvertSurface(gImage, mainSurface->format, 0)) == NULL)
    SDL_LogError(SDL_LOG_CATEGORY_ERROR,
                 "Unable to optimize image %s!\nSDL_image Error: %s\n",
                 basename(filename), IMG_GetError());
SDL_FreeSurface(gImage);

SDL_RenderClear(mainRenderer);
SDL_BlitSurface(frameSurface, NULL, mainSurface, NULL);
SDL_RenderPresent(mainRenderer);

All steps run without errors returned, but it doesn’t display the PNG image.
It works when I replace the call to SDL_BlitSurface by following lines:

frameTexture = SDL_CreateTextureFromSurface(mainRenderer, frameSurface);
SDL_RenderCopy(mainRenderer, frameTexture, NULL, NULL);

The same behavior results when I try to output a text string by following code:

textSurface = TTF_RenderText_Blended(font, string, color);
SDL_BlitSurface(textSurface, NULL, mainSurface, &dstRect);

I don’t understand, why the call to SDL_BlitSurface doesn’t work!
Can somebody help me?

Thanks in advance,
Michael


#2

frameTexture = SDL_CreateTextureFromSurface(mainRenderer, frameSurface);
SDL_RenderCopy(mainRenderer, frameTexture, NULL, NULL);

This looks like it works because you’re using the SDL_Texture structure to hold your image which is what the SDL 2 renderer can handle.

textSurface = TTF_RenderText_Blended(font, string, color);
SDL_BlitSurface(textSurface, NULL, mainSurface, &dstRect);

Does this work in your program. If so, the previous comment would be wrong since this uses the SDL_Surface structure. Haven’t went past SDL 1.2 yet, but read that the renderer is meant for textures, not surfaces.

Not sure this helped, but good luck. Let us know how it goes.


#3

All steps run without errors returned, but it doesn’t display the PNG image.

SDL_RenderPresent will overwrite anything you blitted to the window surface. Also, window surfaces and SDL_Renderers are generally incompatible, and window surfaces are often very slow in general. Instead, your second attempt…

frameTexture = SDL_CreateTextureFromSurface(mainRenderer, frameSurface); SDL_RenderCopy(mainRenderer, frameTexture, NULL, NULL);

This is the correct way to use an SDL_Renderer. You moved your PNG pixels from system RAM to GPU texture memory and then told the GPU to draw it to the screen. :+1:

(You don’t want to call SDL_CreateTextureFromSurface every frame if you can help it. Treat it the same way you do with SDL_ConvertSurface: do it once, then use the results over and over. Once you have an SDL_Texture, you can use SDL_UpdateTexture to update the contents of it efficiently.)


#4

Hello robhilly,
Hello icculus,

it seems, that the call “SDL_BlitSurface” doesn’t work at all, even after the call to “TTF_RenderText_…”

icculus wrote:
“SDL_RenderPresent will overwrite anything you blitted to the window surface. Also, window surfaces and SDL_Renderers are generally incompatible, and window surfaces are often very slow in general.”

I’m rookie using SDL and found only the way to display window changes by calling “SDL_RenderPresent”. Is there an other (faster) way to update the window content?

Thanks in advance
Michael