Renderer : texture not cropped properly when dstRect position is at 0.5f

Hello all,

When the float destination rect position (x or y) is at 0.5f (or very close to it (like 0.501)) , it does not crop from the texture properly.
It crops like I have subtracted 1 from the whole source rect (x,y,w,h).

“direct3d”, “direct3d11”, “direct3d12” - have this issue
“opengl”, “opengles2” - have this issue, but only on x axis
“software” - works fine, does not have this issue
“opengles2” and “metal” - I dont have these

(image 2 part is for “edit 2”)

edit:
I am calling SDL_RenderCopyF(…) with the correct source rect mapping only the white square.
The destination rect x or y can be anywhere like 18.5, 100.5, …
I am using SDL2 version 2.28.3 with SDL2_image 2.6.3 in Visual Studio. I have tried to replace the SDL2.dll with the newest one, but it did not helped.

edit 2:
(look at the image part “image 2”)

SDL_RenderLogicalToWindow(…) input is float, outputs integers. I am at scale 1.
For every RENDER_DRIVER, the output is the same, and it matches the “software” renderer. (0.0 to 0.999: is 0 ; then at 1.0 is 1)
This and SDL_RenderWindowToLogical(…) may cause some issues when calculating collisions or mouse clicks.

At 0.5f they “start” to move to 1. You may need to zoom in, to see the movement, the image self-explains it.
I would like the direct3d and opengl to behave like the software renderer. I think it would be the right behavior.

I remember, I had a similar issue with rotations and position being 1 pixel off.

edit 3:
I should have mentioned, that I am using:
RENDER_SCALE_QUALITY - “nearest”
SDL_RenderSetIntegerScale(…) - true
SDL_RenderSetLogicalSize(…) - some size

edit 4:
The 0.5 changes with the scale - SDL_RenderGetScale(…). For example at scale 2 I have found it is 0.25 and 0.75.

edit 5:
Adding to edit 4: - because 2 * 0.25 = 0.5 and 2* 0.75 = 1.5

I think this could be a well-known problem with Banker-Round.
It doesn’t affect SDLx, but I spent several hours practicing with it until I noticed that the Round command and FPC were behaving strangely. I was told that this happens in the FPU.
You’ll notice this at the latest when you render triangles yourself.

  WriteLn(Round(0.5));  // -> 0
  WriteLn(Round(1.5));  // -> 2
  WriteLn(Round(2.5));  // -> 2
  WriteLn(Round(3.5));  // -> 4
  WriteLn(Round(4.5));  // -> 4

I cannot explain exactly what happens here but I would personally be tempted to put this down as “floating-point rounding errors”. If you want the graphics to be pixel-perfect you might have better luck if you stick to integer coordinates (and integer scaling factors).

I don’t know if this is what’s known as “bleeding” where the colour of nearby pixels can influence the result. To avoid this you might want to add padding around the white rectangle* but if this is a tile that needs to be lined up right next to other tiles then you would still run into problems with occasional gaps unless you stick to integer coordinates/scaling factors.

* With linear scaling mode it’s a bit more complicated to do it properly because even the colour of fully transparent pixels can influence nearby pixels.

I have fixed it with this. It also fixes positions < 0.
I dont like to have extra stuff like this, but I think it is necessary.

The discussion can stay open for some time - maybe there is a bug, or something that I dont know or I am missing.