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.
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.
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.
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.
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.
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.