We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 1308

Summary: Rotation and flipping implementation for accelerated backends
Product: SDL Reporter: Gabriel Jacobo <gabomdq>
Component: videoAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: etc0de, pallavnawani
Version: HG 2.0   
Hardware: All   
OS: All   
Attachments: RenderCopyRotate
RenderCopyRotate cleaned up version
RenderCopyEx, adds rotation and flips to RenderCopy
RenderCopyEx, rotation and flipping for OpenGL, ES1, ES2 and D3D
RenderCopyEx, rotation and flipping for all renderer backends
Test for RenderCopyEx
RenderCopyEx, rotation and flipping for all renderer backends
Test for RenderCopyEx
RenderCopyEx, rotation and flipping for all renderer backends v2

Description Gabriel Jacobo 2011-09-21 09:14:19 UTC
Created attachment 705 [details]
RenderCopyRotate

I had the need to have rotation of sprites in SDL 1.3, and as I've seen a few request along the years to have this implemented I'm leaving this patch here that implements RenderCopyRotate which takes an angle in degrees and a SDL_Point to act as the center of rotation.
I tried to keep it separate from the code of RenderCopyRotate where possible (even though RenderCopy is a special case of RenderCopyRotate with angle=0), at the cost of some code duplication, to make mantaining the patch easier. The notable exception to this being the OpenGL ES 2.0 backend where due to the vertex shaders I had to combine them.

The patch implements rotation in Direct3D, OpenGL, OpenGL ES 1.1, and OpenGL ES 2.0.
Comment 1 Gabriel Jacobo 2011-09-21 15:49:22 UTC
Created attachment 706 [details]
RenderCopyRotate cleaned up version

I've cleaned up the patch a bit, it should be fully independent of RenderCopy now for all the backends supported.
Comment 2 Gabriel Jacobo 2011-10-07 08:48:49 UTC
Created attachment 710 [details]
RenderCopyEx, adds rotation and flips to RenderCopy

I've changed RenderCopyRotate to RenderCopyEx and added flipping as well as rotation. Original plans included color modulation but that's already implemented with sdl texture color and alpha modulation functions.
Comment 3 Ellie 2011-12-29 08:06:46 UTC
Would it be possible that we can both have this in SDL 1.3, and at some point also a software implementation?

The software renderer is a nice fallback and can do scaling already, it would be awesome if this new rotation (which I guess is badly needed due to SDL_gfx as an external lib not really being able to do it in SDL 1.3 with the new accelerated backends) also had a software fallback.

Sure it's going to be slow, but I bet the scaling isn't exactly fast either and software fallbacks are simply good to have.
Comment 4 Sam Lantinga 2012-01-07 21:08:37 UTC
Great patch, thanks!
All we need now is the software rendering version... ;)
Comment 5 Ellie 2012-01-08 01:35:07 UTC
I have just applied the patch to my SDL copy.

There is one big problem with the line numbers in SDL changing with every minor change, which makes this patch hard to apply. However, it still applies fine despite the all the off line numbers which require manual work.

I am willing to look into implementing this for the software renderer but I don't know if I'm up to it. I just hope we can get this into mainstream soon (with or without software renderer implementation), so that not everyone else who wants to have this essential and very useful functionality has to go through the same patching oddness again. Looking forward to rotation in SDL! :-)
Comment 6 Ellie 2012-01-08 03:25:58 UTC
Well I digged the source a bit. The idea is to write some additional function to SDL_BlitScaled, SDL_BlitScaledRotatedFlipped or something, I guess.

The code from SDL_UpperBlitScaled is already too scaling-specific to be used really, since the dest-clipping doesn't make much sense when it's rotated afterwards.

Now I think I could do is provide an alternative to SDL_stretch.c which also handles rotation, I'd suggest naming it SDL_stretchrotation.c. The problem is however, that the only approach I can think of would be fairly slow:

First, rotate the corner points of the scaled dest rectangle, then make a new rectangle that has the minimum required dimensions to keep them all.
Then, iterate all points of that new rectangle, and rotate the points on it back with negative/backwards rotation applied, reverse-apply scale and see where we land and get the pixel value from there (or do nothing when it is outside the image bounds).

If someone has a better idea, then shoot. Or maybe that person with a better idea wants to implement it instead of me :) I'm not exactly a lowlevel ubercoder.

The things above such an SDL_stretchrotation.c implementation seem fairly trivial to me and just a matter of how to organise things and adding the proper checks.
Comment 7 Ellie 2012-01-08 03:26:50 UTC
Well forget about the name SDL_stretchrotation.c, should be SDL_stretchrotate.c rather.
Comment 8 Ellie 2012-01-08 03:29:40 UTC
Of course, we could also try to borrow from SDL_gfx here. I don't know how good its code is, but I guess it might be a lot better than what I could spontaneously come up with. But I suppose we'd need to sort out the licensing first?
Comment 9 Gabriel Jacobo 2012-01-08 06:08:24 UTC
Hey Sam, can we incorporate this and place a dummy version of the software renderer equivalent? I promise to give it a shot next week if that's what will get this functionality incorporated. Thanks!
Comment 10 Sam Lantinga 2012-01-08 10:47:07 UTC
There's another implementation of the flipping in bug 1181.

I would raise it on the mailing list and see what people think, especially with regards to the software renderer.  I'm not opposed to adding CopyEx with flip/rotate with an angle, although a pivot point seems like overkill to me.  I like what you did there about making it optional though.
Comment 11 Gabriel Jacobo 2012-01-23 07:22:02 UTC
Created attachment 798 [details]
RenderCopyEx, rotation and flipping for OpenGL, ES1, ES2 and D3D

Updating patch, applies cleanly on current tip.
Comment 12 Gabriel Jacobo 2012-01-23 17:06:33 UTC
Created attachment 801 [details]
RenderCopyEx, rotation and flipping for all renderer backends

Attaching new patch with a first pass at a software renderer, 99.9% lifted from SDL_gfx. With the test I'm running it behaves almost like the OpenGL one minus some clipping issues I've still got to figure out. Feedback is welcome!
Comment 13 Gabriel Jacobo 2012-01-23 17:07:06 UTC
Created attachment 802 [details]
Test for RenderCopyEx
Comment 14 Gabriel Jacobo 2012-01-25 08:31:20 UTC
Created attachment 805 [details]
RenderCopyEx, rotation and flipping for all renderer backends

Attaching cleaned up patch, the software backend seems to work nicely, I'm getting 130fps with the test in my machine (vs 3300fps with OpenGL!).
Comment 15 Gabriel Jacobo 2012-01-25 08:36:27 UTC
Created attachment 806 [details]
Test for RenderCopyEx
Comment 16 Gabriel Jacobo 2012-02-08 14:17:19 UTC
So, the vote on the list so far is an overwhelming 3 yay (including my vote), 0 nay, 1 "why don't you do something else entirely". It's not the massive endorsement/petty fight I expected, but is it enough?
Comment 17 Pallav Nawani 2012-04-04 05:06:48 UTC
Still waiting for a decision on this.
Comment 18 Gabriel Jacobo 2012-04-04 05:36:54 UTC
Sam has said that this will likely be incorporated, I'll poke him when I have a chance to see if we can get it done soon.
Comment 19 Pallav Nawani 2012-04-20 03:15:20 UTC
Compilation issues under Win7, VC 2008 Express, Dx2007 SDK with the patch applied.

The issues are related to use of functions sin(), cos(), fabs(), ceil(), memset() in SDL_rotate.c. Replacing sin(), cos() etc with SDL_sin(), SDL_cos() etc fixes the problem, but I don't know how it will affect compilation under other platforms.

Also in SDL_render_d3d.c, there is an compilation issue because of use of sprintf() on line 472. Can be fixed by switching to SDL_snprintf().

Also, in SW_RenderCopyEx() in SDL_render_sw.c, the variable 'retval' can possibly be used uninitialized in one particular case, so perhaps it should be initialized to -1 beforehand.
Comment 20 Gabriel Jacobo 2012-04-21 07:17:22 UTC
Thanks! Good catches! Sam, can we incorporate this patch with those fixes Pallav mentions?
Comment 21 Sam Lantinga 2012-05-12 06:30:41 UTC
Sure!  Have you already updated the patch with those changes?
Comment 22 Gabriel Jacobo 2012-05-12 06:58:14 UTC
Created attachment 852 [details]
RenderCopyEx, rotation and flipping for all renderer backends v2

Attaching patch with Pallav Nawani's comments incorporated. I verified that it compiles under Linux (not Visual Studio)
Comment 23 Gabriel Jacobo 2012-06-01 15:52:17 UTC
http://hg.libsdl.org/SDL/rev/6077a1310907