Rotating texture with even dimensions by 90 degree

Hey all,

I’m working with c++ and SDL2 on a very basic game. Because i use very small images (max. 64x64) it is important for me to be pixel accurate. But when I try to rotate an e.g. 10x10 image by multiples of 90?? they get shifted as shown in the following:

[Image: http://i.stack.imgur.com/QWGfC.jpg ]

I guess that’s happening because the center is picked as pixel (5,5), which is not the center but actually a little off to the right bottom. The actual center point should be the line between (4,4)and (5,5), but SDL doesn’t allow float values when rendering. Even though the 10x10 image is perfectly rotatable (works in e.g. Gimp) SDL doesn’t seem to take the even dimensions of the texture into account.

So is there a way to correctly rotate images in SDL or do i have to check the angle by hand and if it is a multiple of 90?? shift it back myself after rotation? For angles that are not multiples of 90?? i don’t care as much, because the image will be quite destorted when looking at the individual pixels and you wouldn’t recognise a shift by 1 pixel as easy.

Thanks and best regards,
Stefan

Am i really the first and only one with this problem? Or am I or my code the problem?
Just to give as much information as possible, here is the original image and the code, which created the (zoomed in) example image on the original post:

[Image: http://i.imgur.com/W8iHtgA.png ]

Code:

SDL_Surface* rotationTestSurface = IMG_Load(“rotationTest.png”);
SDL_Texture* rotationTestTexture = SDL_CreateTextureFromSurface(renderer, rotationTestSurface);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 100);
for (int i = 0; i < 4; i++) {
SDL_Rect drawRect{ 100,100+i15,10,10 };
SDL_RenderCopyEx(renderer, rotationTestTexture, NULL, &drawRect, i
90, NULL, SDL_FLIP_NONE);
SDL_RenderDrawRect(renderer, &drawRect);
}

And here is why this (erroneous) behavior is a big problem for me. I’m making a turn and grid based game. The red square is the player and the black line is it’s movement path, which looks horrible because of the incorrect rotations of the single pieces (straights and corners):
[Image: http://i.imgur.com/GnSzYBi.png ] [Image: http://i.imgur.com/tlvF3Ir.png ]

[Image: http://i.imgur.com/wdV6sLC.png ]

Hopefully i get some answers now, even if it’s just other users with the same problem.

Thanks and best regards,
Stefan

Still no answers? I thought there were even some devs of SDL here?
In the meantime i used a dirtly hack that just shifted the rotated textures back by one pixel, but when combining the rotation witn a scaling operation the problem is even worse, so help is still highly appreciated…

My guess is that you’re pretty much the only one using that feature
with a pixel precision requirement at this point. (I’m not using it in
Kobo Redux, for example, because rotating sprites and tiles breaks any
any directional lighting the art may have.)

It may also be that the problem only occurs on certain platforms or drivers.

Anyway, when dealing with a 3D API, you typically have to take the
size of pixels and texels in account, and more specifically, make sure
your texel filters hit the center of pixels, rather than one of the
corners. With filtering (biliniar or similar), it’s not all that
critical, but with “nearest”, even the slightest rounding error in the
wrong direction means you get the wrong texel. A “2D” API built over a
3D API, like the SDL one, is supposed to take care of this internally,
as it’s generally not accessible through such an API.

So, I suspect it’s a rounding error in the transform, and either SDL
isn’t taking that in account, or it only happens in certain
environments. Have you tried using other SDL renderers (OpenGL, D3D,
software…), or running it on a different OS, or just another
computer, to see if the problem is still there?On Mon, Aug 1, 2016 at 2:28 AM, stewambo wrote:

Still no answers? I thought there were even some devs of SDL here?
In the meantime i used a dirtly hack that just shifted the rotated textures
back by one pixel, but when combining the rotation witn a scaling operation
the problem is even worse, so help is still highly appreciated…


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://consulting.olofson.net http://olofsonarcade.com |
’---------------------------------------------------------------------’

Hi,

Maybe you are hitting this bug:
https://bugzilla.libsdl.org/show_bug.cgi?id=2421
I have just added a test-case for rotations 0 / 90 / 180 / 270.

It fails for the “software” renderer with sometimes: offset, or image
truncation.
But it works for opengl, opengles and opengles2 renderers.

I haven’t tested it with windows direct3d … If you’re on windows, you may
want to try a patch including in this bug.

Hope it helps,
SylvainOn 7 August 2016 at 13:48, David Olofson wrote:

My guess is that you’re pretty much the only one using that feature
with a pixel precision requirement at this point. (I’m not using it in
Kobo Redux, for example, because rotating sprites and tiles breaks any
any directional lighting the art may have.)

It may also be that the problem only occurs on certain platforms or
drivers.

Anyway, when dealing with a 3D API, you typically have to take the
size of pixels and texels in account, and more specifically, make sure
your texel filters hit the center of pixels, rather than one of the
corners. With filtering (biliniar or similar), it’s not all that
critical, but with “nearest”, even the slightest rounding error in the
wrong direction means you get the wrong texel. A “2D” API built over a
3D API, like the SDL one, is supposed to take care of this internally,
as it’s generally not accessible through such an API.

So, I suspect it’s a rounding error in the transform, and either SDL
isn’t taking that in account, or it only happens in certain
environments. Have you tried using other SDL renderers (OpenGL, D3D,
software…), or running it on a different OS, or just another
computer, to see if the problem is still there?

On Mon, Aug 1, 2016 at 2:28 AM, stewambo wrote:

Still no answers? I thought there were even some devs of SDL here?
In the meantime i used a dirtly hack that just shifted the rotated
textures
back by one pixel, but when combining the rotation witn a scaling
operation
the problem is even worse, so help is still highly appreciated…


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://consulting.olofson.net http://olofsonarcade.com |
’---------------------------------------------------------------------’


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Sylvain Becker

Thanks for the answers guys :slight_smile:

By now i pretty much figured that out by myself. When i wanted to submit this as a bug i found the following: https://bugzilla.libsdl.org/show_bug.cgi?id=1822 So than i tried using different renderers and found out, that using opengl was pixel precise. However the rotation still looked wrong when scaling the texture to half its size, which i fixed by switching from nearest to linear scaling quality.

Just for your info before I used the direct3d renderer under windows, which produced the image i already showed you.