I’m trying to understand what the point of setting a viewport is and I haven’t found any decent explanation for it. The problem I have is that this code:
// Using a viewport
SDL_RenderCopy(&renderer, &texture, nullptr, nullptr);
produces the exact same result as this code:
// Using a destination rect
SDL_RenderCopy(&renderer, &texture, nullptr, &viewportRect);
The only difference I can see is if you try to render something outside of the viewport it isn’t rendered. So what am I missing about this?
Custom viewports let you confine and scale your drawing to one area of the screen without your drawing code having to know about it or care if you don’t want it to.
So one possible use would be if you had an in-game level editor, maybe with one area on screen that’s a level viewer and the rest is editor widgets. When you draw the level viewer, set a custom viewport and then just call your normal level rendering code. Everything will be contained within that viewport and scaled to fit.
Not rendering anything drawn outside the viewport is exactly the point, and exactly the advantage.
One nice use I’ve found for them is marquis-style scrolling text. Rather than wrap your text render function in another function that can draw part of a letter/line, or rather than try to draw only part of the rendered image, just throw a viewport in there and you’re good to go. I used this for an in-game window that can have an arbitrary number of lines of text in it.
The same concept applies for minimaps and stuff too. If you have an icon that’s on the edge of the minimap’s range, it’ll automatically be truncated if you define that boundary with a viewport.
Allow me to correct myself. If all you need to do is clip rendering, you also have SDL_SetClipRect(), which is actually a lot easier to use in certain cases. Viewports will clip rendering, like I mentioned above, but they’re more specialized–they’re designed to divide the window. As a result, they’ll do weird stuff if you try to overlap the edge of the screen.
I just ran into a problem with a text box I had made that I fixed by switching from a Viewport to a ClipRect. Using my same marquis window from the above post, I wanted the window itself to move onscreen and off screen as the information on it is requested. Using a Viewport, it had weird behavior–either drawing nothing, or drawing the text at the boundary of the screen when I wanted it halfway off screen instead. This is because this isn’t what Viewports are for.
After switching to a ClipRect, I no longer have any problems.
So my above example of using a Viewport for marquis text is incorrect. It will still probably work in some cases, but it’s a more general problem than the Viewport is designed for, and there are better ways to do it. Viewports are specifically for dividing the screen, for minimaps, split screens, menu panels, etc.