sdl-gpu
sdl-gpu copied to clipboard
why is GPU_SNAP_POSITION_AND_DIMENSIONS default, and why does it truncate instead of round?
I have some bitmap fonts in my game, and they were coming out misaligned, like one letter would be a pixel too high or spaced one pixel too much to the right, etc.
I knew it was a rounding issue, but I couldn't see the rounding problem in my code.
I traced into
static void BlitTransformX(GPU_Renderer* renderer, GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y, float pivot_x, float pivot_y, float degrees, float scaleX, float scaleY)
and found this:
if(image->snap_mode == GPU_SNAP_POSITION || image->snap_mode == GPU_SNAP_POSITION_AND_DIMENSIONS)
{
// Avoid rounding errors in texture sampling by insisting on integral pixel positions
x = floorf(x);
y = floorf(y);
}
When I used
GPU_SetSnapMode( this->_image, GPU_SNAP_NONE );
on my images, it fixed the alignment issues.
So my questions are:
(1) Why is GPU_SNAP_POSITION_AND_DIMENSIONS the default for images? Is it because it's more efficient than not snapping? Is it because most people want snapping? Why do they want snapping if it can mess up intended positioning? If it's because it's more efficient, how much more efficient is it?
(2) When snapping, why not round instead of floor? Wouldn't rounding give better results?
(1) The default behavior was set to avoid blurring effects due to filtering between pixels. This appears when blitting on-center using an image with odd dimensions or when a non-integer position is used.
(2) The snapping still has some kinks to dig into, so it may be that rounding is preferable in some cases. floor
was used because floats would be truncated when passed to a function taking ints instead (e.g. in the SDL rendering functions).
Well, it might be worth adding a note to README.md explaining that people with my use case probably want to use GPU_SNAP_NONE, where "my use case" is what I think of as a standard "sprite and bitmap font" based game. Intuitively, it sounds like snapping is what I'd want, since everything in my game is supposed to happen with integer pixels, but of course when I'm scaling to fit on a screen that doesn't match the art, fractional pixels come into play. But still it's surprising that I have to switch the default setting to get my sprites to line up properly (e.g., my letters to not jump up and down relative to the baseline).