SDL3: Successfully drawn, but no image displayed




Click this button to clear the background color settings and repeat drawing four images on top. There is a probability that it has not been drawn.
Did I write the code incorrectly?

As we have told you before, you should redraw the whole screen and only call RenderPresent once.

nonono look at code,I am using targetTexture, instead of displaying all images at once, I need to display them one by one.

instead of displaying all images at once, I need to display them one by one.

I thought you were drawing four images side by side?

look at code,I am using targetTexture

Yes, but you don’t need to call RenderPresent after each image that you draw. Call it at the end of the function instead (assuming that that function contains all the code for drawing the whole screen).


Pay special attention to the following sentences in the docs:

when using SDL’s rendering API, one does all drawing intended for the frame, and then calls this function once per frame to present the final drawing to the user.

The backbuffer should be considered invalidated after each present; do not assume that previous contents will exist between frames.

Rendering to targetTexture overcomes the invalidation problem but you should still only call RenderPresent once per frame.

The OP states that “instead of displaying all images at once, I need to display them one by one” so he does need to call RenderPresent() more than once to achieve that.

In my experience, that’s common when using a target texture. After all, if you’re able to render the entire screen contents before calling RenderPresent(), why use a target texture at all?

Hmm, but he renders all images inside the same function? Why not just render all of them to the texture and call RenderPresent at the end? Calling it multiple times will just slow things down, especially when vsync is enabled.

1 Like

Yes, but if that’s the effect the OP wants I don’t see any reason to object to it; I’ve done similar things myself in the past. It should work and does not explain the “no image displayed” issue that he is encountering.

Yes, I have my own reasons for calling ‘persist’ every time, because in real projects, I need to use it this way. The above is just an example of imitating a real environment.

The problem I am facing now is that the target texture of SDL3 has such an error, while I have also tried to write a similar demo for SDL2, but everything is normal.

1 Like

In real projects, they are not executed in one method, but in the same thread in sequence, so in the minimum demo, I put them in one method.

1 Like

Could it be the call to RenderClear that is causing it? If the render target is targetTexture when the Button_Click function is called it will end up clearing targetTexture which I don’t think is the intention.

What I want to express is that I draw the image onto the target texture and then render the target texture. However, the target texture being rendered did not display properly.

I don’t think so. After thinking about it, I think my usage of the target texture should be correct. It works fine in sdl2, but there were some unexpected situations in sdl3.

I also tried to write a small demo directly using C, and the result was unexpected.

int main(void) {
    printf("Hello world\n");
    SDL_Window *window;
    SDL_Renderer *renderer;
    SDL_Texture *targetTexture;
    SDL_Event event;
    SDL_Init(SDL_INIT_VIDEO);

    window = SDL_CreateWindow("SDL3", 1920, 1080,SDL_WINDOW_RESIZABLE);
    renderer = SDL_CreateRenderer(window,NULL);
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
    SDL_RenderClear(renderer);
    SDL_RenderPresent(renderer);
    targetTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 1920, 1080);
    SDL_SetRenderTarget(renderer, targetTexture);
    printf("%p\n", window);
    while (1) {
        SDL_PollEvent(&event);
        if (event.type == SDL_EVENT_QUIT) {
            break;
        }

        if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
            printf("mouse button down\n");
            SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255);
            SDL_RenderClear(renderer);
            SDL_SetRenderTarget(renderer, NULL);
            SDL_RenderTexture(renderer, targetTexture,NULL,NULL);
            SDL_RenderPresent(renderer);
            SDL_SetRenderTarget(renderer, targetTexture);

            SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
            SDL_RenderClear(renderer);
            SDL_SetRenderTarget(renderer, NULL);
            SDL_FRect  frect=(SDL_FRect){0,0,1920/2,1080/2};
            SDL_RenderTexture(renderer, targetTexture,NULL,&frect);
            SDL_RenderPresent(renderer);
            SDL_SetRenderTarget(renderer, targetTexture);

            SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
            SDL_RenderClear(renderer);
            SDL_SetRenderTarget(renderer, NULL);
              frect=(SDL_FRect){1920/2,0,1920/2,1080/2};
            SDL_RenderTexture(renderer, targetTexture,NULL,&frect);
            SDL_RenderPresent(renderer);
            SDL_SetRenderTarget(renderer, targetTexture);

            SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
            SDL_RenderClear(renderer);
            SDL_SetRenderTarget(renderer, NULL);
            frect=(SDL_FRect){0,1080/2,1920/2,1080/2};
            SDL_RenderTexture(renderer, targetTexture,NULL,&frect);
            SDL_RenderPresent(renderer);
            SDL_SetRenderTarget(renderer, targetTexture);

            SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
            SDL_RenderClear(renderer);
            SDL_SetRenderTarget(renderer, NULL);
            frect=(SDL_FRect){1920/2,1080/2,1920/2,1080/2};
            SDL_RenderTexture(renderer, targetTexture,NULL,&frect);
            SDL_RenderPresent(renderer);
            SDL_SetRenderTarget(renderer, targetTexture);
        }
    }
    return 0;
}

I submitted my code to Slouken and I would like to wait for his response.
SDL3: Successfully drawn, but no image displayed ¡ Issue #12592 ¡ libsdl-org/SDL

I know that on some platforms (even in SDL2) it is necessary to poll for events in order for rendering to work correctly. Try restructuring your code so that you always call SDL_PollEvent() between any two consecutive calls to SDL_RenderPresent().

That last program clearly clears the targetTexture.

...
SDL_SetRenderTarget(renderer, targetTexture); // <-- targetTexture becomes the render target

SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer); // <-- targetTexture is cleared
SDL_SetRenderTarget(renderer, NULL);
SDL_FRect  frect=(SDL_FRect){0,0,1920/2,1080/2};
SDL_RenderTexture(renderer, targetTexture,NULL,&frect);
SDL_RenderPresent(renderer);
SDL_SetRenderTarget(renderer, targetTexture);
...

I’m guessing that clearing the texture will make it transparent. This means that you will be showing parts of the screen that has not been redrawn since last call to SDL_RenderPresent. This is a problem because those parts have been “invalidated” and might show up as garbage.

SDL_SetRenderTarget(renderer, targetTexture);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer);
This is not clearing the texture, I think it refreshes the entire background color of the target texture.

1 Like

He explicitly clears it to opaque (alpha = 255):

SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);

Using SDL_RenderClear() is a fast way of clearing the target texture and perfectly valid as far as I’m aware.

1 Like

Ah, you’re right. I don’t know what I was thinking.

I believe that the problem that I described is still there but for a different reason.

You draw targetTexture over a part of the screen …

SDL_RenderTexture(renderer, targetTexture,NULL,&frect);

… so …

This doesn’t explain why the whole screen show up as “garbage” (at least one part should be a solid colour) so there is probably other problems as well.