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.
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”.
// 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.
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.
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)
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.