The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Rotating texture with even dimensions by 90 degree
stewambo


Joined: 04 Jun 2016
Posts: 13
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:



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
stewambo


Joined: 04 Jun 2016
Posts: 13
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:





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+i*15,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):





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

Thanks and best regards,
Stefan
SeanOConnor


Joined: 15 Jun 2016
Posts: 9
I've recently got into SDL and I'm finding the same thing. My guess is it's because SDL uses ints for pixel positions, when it ought to use floats. Maybe using ints is a throwback to the days before OpenGL/DirectX when it only made sense to draw at integer pixel positions?

My game Firefight is a real-time WW2 game and when the tanks move their turrets (which are drawn separately from the tank hulls so that they can rotate on them) jiggle about relative to the hull. I didn't have that problem with the code when it was Objective C and running with my own OpenGL code which used floats, but I do get the problem with SDL and its ints.

I can live with it for now but when I get some spare time I might look into the SDL code and see if it's possible to use floats instead of ints for the rendering.
stewambo


Joined: 04 Jun 2016
Posts: 13
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...
Rotating texture with even dimensions by 90 degree
David Olofson
Guest

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:
Quote:
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

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

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Rotating texture with even dimensions by 90 degree
slvn


Joined: 06 Oct 2012
Posts: 88
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,

Sylvain














On 7 August 2016 at 13:48, David Olofson wrote:
Quote:
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:
Quote:
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...



Quote:
_______________________________________________
SDL mailing list

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

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org



--
Sylvain Becker
stewambo


Joined: 04 Jun 2016
Posts: 13
Thanks for the answers guys 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.