SDL How to only draw a certain area without affecting the rendering of other areas

Assuming the length of videoTextureForSquare is 4, there are a total of four cameras. When I draw the first camera, I also need to copy and draw the other three, right?

In my code, I haven’t done frame synchronization, so I must need to repeatedly call renderpresent because each frame of the four cameras doesn’t arrive at the same time.

I think you’re getting confused. SDL_RenderCopy() isn’t actually copying anything, it just means you want SDL to draw that texture at the specified place on screen.

Create and keep one texture per camera, put them in an array. If a camera has a new video frame, update its corresponding texture with the new frame. If there are no new video frames, there’s no updating to be done. No synchronization needed.

And yes, you’re drawing each camera every screen frame, but drawing 25 textures to the screen is almost instantaneous even on really old GPUs.

Wait a moment, I’ll draw a rough flowchart for you to see if it’s correct

That isn’t what SDL_RenderPresent() does. You only need to call it once, at the end, when you want everything to be shown to the user.


Look at this.
Is this the logic of your code?

I think the confusion is because your earlier codes called sdl.RenderPresent(Renderer); twice, and you also called it from “the code to decode each frame”.


This is my code logic

Let me give you an updated example:

// videoTextures is an array of SDL textures

bool keepRunning = true;

while(keepRunning) {
	// we don't need to mess with render targets
	// this is C pseudocode because I don't know what language you're using
	SDL_SetRenderDrawColor(255, 255, 255, 255); // or whatever your border color is
	SDL_RenderClear(renderer);

	for(int currentCamera = 0; currentCamera < numberOfCameras; currentCamera++) {
		// If we have a new frame for the current camera, update its texture
		if(cameraHasNewFrame(currentCamera)) {
			uploadCameraFrameToTexture(currentCamera, videoTextures[currentCamera]);
		}

		SDL_Rect drawRect;
 		// TODO: compute drawRect based on where on screen this should go
		// then inset it by 1 pixel on each side, so we have a border
    
		SDL_RenderCopy(renderer, videoTextureForSquare[currentCamera], NULL, &drawRect);
	}

	// TODO: draw "No Video" for empty squares, like if there's 1 camera but 4 squares

	// YOU SHOULD ONLY EVER CALL THIS ONCE PER SCREEN FRAME, AT THE VERY END
	SDL_RenderPresent(renderer);
}

This isn’t going to work. Every time you call SDL_RenderPresent() it is telling SDL that you’re finished drawing and to “present” it to the user on screen.

Yes, every time I call renderpresent, there is a new frame that needs to be drawn.

Not a new video frame. SDL_RenderPresent() is for when the entire frame (not a single video frame from a camera) is finished and you’re ready to show it on the screen.

You should only call RenderPresent after you have redrawn the whole screen. To avoid code duplication (and avoid the mistakes that are likely to come from it) it’s best to only do it in one place. Many applications (especially games) run a loop, and each iteration of the loop represents one “frame”, so they simply redraw everything each loop iteration. If your application is different and you need to redraw the screen at odd times at least put the rendering code inside a function so that you can call that function whenever you need to redraw the screen. This function should only call RenderPresent once.

That’s right, you imagine the targettexture as a piece of paper. When the camera takes a new frame, I update the corresponding area of this paper while keeping the rest unchanged. Then when I rendered it to the screen, I rendered the entire piece of paper.

yes,My code is just a demo. Used to test whether it is feasible.

Just like I have two buttons, the first button I want to see a red rectangle on the screen, and the second button I want to add a green rectangle next to the red rectangle.
So I called twice (renderpresent)

But why?

Just draw both buttons (and everything else) and then call RenderPresent once.


Click the first button, I want to see this

Click the second button, I want to see this.
So I need to call it twice, assuming I clicked the button twice.

I think it was my poor English proficiency that led to our misunderstanding.

You indeed need to call RenderPresent once each time you redraw the screen. That’s unavoidable and totally fine. Our concern was more about calling RenderPresent when you were not finished drawing the whole screen.