Not sure what the point of the new Viewport stuff is, but it’s breaking resizing
pretty badly. When I take my TSdlFrame component and run the following, I get
exactly what you’d expect: a red box in the upper-left corner. (Yes, it’s my
own object and the API isn’t familiar. Assume everything does what it
intuitively looks like it should.)
begin
sdlFrame1.Clear;
sdlFrame1.DrawBox(rect(0, 0, 50, 50), COLOR_RED);
sdlFrame1.Flip;
end;
If I then execute a second routine,
begin
sdlFrame1.Height := round(sdlFrame1.Height * 0.9);
end;
the frame becomes a bit less tall. If I run the box-drawing routine again after
this, I’d expect to see the same thing as before: a red box in the upper-left
corner. But that’s not what I see. I get a red box drawn with the origin
slightly above the upper-left corner, so the top line is missing.
The problem seems to be coming from the following block in
SDL_RendererEventWatch:
if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
/* Try to keep the previous viewport centered */
int w, h;
SDL_Rect viewport;
SDL_GetWindowSize(window, &w, &h);
viewport.x = (w - renderer->viewport.w) / 2;
viewport.y = (h - renderer->viewport.h) / 2;
viewport.w = renderer->viewport.w;
viewport.h = renderer->viewport.h;
SDL_RenderSetViewport(renderer, &viewport);
}
It tries to keep the viewport “centered”, but doesn’t do anything to ensure
proportionality or bounds checking. According to the inline documentation for
SDL_RenderSetViewport, “When the window is resized, the current viewport is
automatically centered within the new window size.” Unfortunately, there’s no
code there to handle the default case, “not using a viewport”.
This can be handled one of two ways. Either a SDL_Bool flag on the renderer
struct indicating whether a non-standard viewport has been set, or a pair of
floats describing the ratio between the heights and widths of the window and the
viewport to maintain proportionality. Whichever one is chosen needs to be taken
into account in SDL_RendererEventWatch.