| Summary: | Renderer doesn't use entirely the viewport/clip rect when scaling is used | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Sylvain <sylvain.becker> |
| Component: | render | Assignee: | Sam Lantinga <slouken> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | ||
| Version: | HG 2.1 | ||
| Hardware: | All | ||
| OS: | All | ||
| Attachments: |
test case
test-case 2 |
||
Here's a patch: https://hg.libsdl.org/SDL/rev/81c663ee1c2b Some explanation: When scaling has been added: https://hg.libsdl.org/SDL/rev/e978048ced60 width and height are computed using SDL_ceil: renderer->viewport.w = (int)SDL_ceil(rect->w * renderer->scale.x); renderer->viewport.h = (int)SDL_ceil(rect->h * renderer->scale.y); and also for clip rect. And later, for integer scaling, and scale policy modes. But, renderers never use SDL_ceil() inside. But they use SDL_floor instead, implicitly. eg software: https://hg.libsdl.org/SDL/file/81c663ee1c2b/src/render/software/SDL_render_sw.c#l290 It's the same for all renderers, at many functions/places. The difference appear when copies a texture which is intersected with viewports. (see the testcase) Created attachment 4628 [details] test-case 2 Another test-case for a similar issue. Fix: add SDL_RenderGetViewportF to prevent rounding viewport values and scaling again, which loses precision. And which provides a different result compared to the clip rect. https://hg.libsdl.org/SDL/rev/7e5622af3e16 https://hg.libsdl.org/SDL/rev/134e68667500 Fix issue with previous function https://hg.libsdl.org/SDL/rev/ab11d64eee23 No need of SDL_RenderGetViewportF(), but only the width and height. |
Created attachment 4617 [details] test case Using any renderer with scaling, Copying a texture to the full output size, it doesn't fully fill the display area (define by viewport or clip rect). 1 pixel line is missing. It can be shown when using a second texture, and drawing half outside the display. this 2nd texture is intersected with the viewport/clip rect, and goes 1 pixel after the 1st texture. Test-case added