Rotation API

I’ve seen a bunch of people asking about rotating and zooming and doing both
together on here. We’ve got the zooming working, now we need rotation. And
it doesn’t seem to me that that’s all that difficult, at least not for either OpenGL
or Direct3D.

The exact implementation details vary a bit, but in both systems, you render a
rectangular texture by specifying the locations of the four corners (vertices)
and associating the resulting quad it with a texture. Thing is, there’s no
requirement for the edges of your quad to be parallel to the edges of the
screen, or even for your quad to be rectangular at all.

Rotation, then, becomes trivial to anyone with a moderate knowledge of trig.
Input the original (unrotated) rectangle and an angle, calculate the
positions of the four vertices after applying the rotation, and send those to
GL/D3D.

How about something like this:

int SDL_RenderZoom(SDL_Texture * texture, const SDL_Rect * srcrect,
const SDL_Rect * dstrect, int angle);

Using int for the angle makes it easier to calculate this by using precomputed
sine and cosine tables. This could be made a float for extra precision if
anyone really cares about rotations smaller than 1/360 of a circle. The
center of the resulting quad would be the center of dstrect.

This would be more difficult to implement on non-accelerated backends, of
course. Perhaps it could be unimplemented, or fall back to something like
the rotozoom function on SDL_gfx.

This API would, of course, be much more useful in conjunction with render
targets.

Any thoughts?

Hi,

I think SDL 1.3 SHOULD HAVE built-in functions to
scale and rotate an SDL_Surface…

Scaling and rotating are IMPORTANT functions
when programming a 2d video game!

If you want a Linux demo that shows
SDL 1.2 + OpenGL with image scaling and rotating,
then check out my new demo here:
http://forums.libsdl.org/viewtopic.php?t=5995

JeZ+Lee
SLNTHERO at aol.com
Silent Hero Productions®
Video Game Design Studio
www.SilentHeroProductions.com

Mason Wheeler wrote:> I’ve seen a bunch of people asking about rotating and zooming and doing both

together on here. We’ve got the zooming working, now we need rotation. And
it doesn’t seem to me that that’s all that difficult, at least not for either OpenGL
or Direct3D.

The exact implementation details vary a bit, but in both systems, you render a
rectangular texture by specifying the locations of the four corners (vertices)
and associating the resulting quad it with a texture. Thing is, there’s no
requirement for the edges of your quad to be parallel to the edges of the
screen, or even for your quad to be rectangular at all.

Rotation, then, becomes trivial to anyone with a moderate knowledge of trig.
Input the original (unrotated) rectangle and an angle, calculate the
positions of the four vertices after applying the rotation, and send those to
GL/D3D.

How about something like this:

int SDL_RenderZoom(SDL_Texture * texture, const SDL_Rect * srcrect,
const SDL_Rect * dstrect, int angle);

Using int for the angle makes it easier to calculate this by using precomputed
sine and cosine tables. This could be made a float for extra precision if
anyone really cares about rotations smaller than 1/360 of a circle. The
center of the resulting quad would be the center of dstrect.

This would be more difficult to implement on non-accelerated backends, of
course. Perhaps it could be unimplemented, or fall back to something like
the rotozoom function on SDL_gfx.

This API would, of course, be much more useful in conjunction with render
targets.

Any thoughts?


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

Rotation is good. SDL_RenderZoom is a bad name for it. I prefer floats,
but if you want more precision using ints, then you can measure the angle in
minutes or tenths of a degree.

Jonny DOn Wed, Feb 17, 2010 at 3:02 PM, Mason Wheeler wrote:

I’ve seen a bunch of people asking about rotating and zooming and doing
both
together on here. We’ve got the zooming working, now we need rotation.
And
it doesn’t seem to me that that’s all that difficult, at least not for
either OpenGL
or Direct3D.

The exact implementation details vary a bit, but in both systems, you
render a
rectangular texture by specifying the locations of the four corners
(vertices)
and associating the resulting quad it with a texture. Thing is, there’s no
requirement for the edges of your quad to be parallel to the edges of the
screen, or even for your quad to be rectangular at all.

Rotation, then, becomes trivial to anyone with a moderate knowledge of
trig.
Input the original (unrotated) rectangle and an angle, calculate the
positions of the four vertices after applying the rotation, and send those
to
GL/D3D.

How about something like this:

int SDL_RenderZoom(SDL_Texture * texture, const SDL_Rect * srcrect,
const SDL_Rect * dstrect, int angle);

Using int for the angle makes it easier to calculate this by using
precomputed
sine and cosine tables. This could be made a float for extra precision if
anyone really cares about rotations smaller than 1/360 of a circle. The
center of the resulting quad would be the center of dstrect.

This would be more difficult to implement on non-accelerated backends, of
course. Perhaps it could be unimplemented, or fall back to something like
the rotozoom function on SDL_gfx.

This API would, of course, be much more useful in conjunction with render
targets.

Any thoughts?


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

SOME 2d video games. Not all. :slight_smile: Tetris, Mario, Zelda, Lemmings,
SimCity, Warcraft, Bomberman, Space Invaders, most any board game…
there are many, many other games that don’t require scaling/rotating.

Not that I don’t think it would be USEFUL, mind you, but there’s
already SDL_gfx/SDL_rotozoom. Why duplicate effort?On Wed, Feb 17, 2010 at 3:11 PM, Jesse Palser wrote:

Scaling and rotating are IMPORTANT functions
when programming a 2d video game!

Not that I don’t think it would be USEFUL, mind you, but there’s
already SDL_gfx/SDL_rotozoom. Why duplicate effort?

Because SDL_rotozoom isn’t suitable for SDL 1.3 work. It only
works on SDL_Surfaces, before the surface->texture conversion.
Let’s say you have an image that you want to make spin around
on screen, rotating 3 degrees every frame. To do this the
SDL_gfx way, you’d have to allocate 120 different SDL_Surfaces,
perform 120 (slow) rotozoom operations, and convert the 120
results into 120 textures, and then keep track of them all.

Or you could create one texture and let the graphics card handle
the heavy lifting.>----- Original Message ----

From: Justin Coleman
Subject: Re: [SDL] Rotation API - Also scaling

Jonny D wrote:

Rotation is good. ?SDL_RenderZoom is a bad name for it. ?I prefer floats, but if you want more precision using ints, then you can measure the angle in minutes or tenths of a degree.

floats would be more logical to the programmer. Although SDL may be(come) available on systems without a FPU, I don’t think the overhead from software operations would be too large for this function (it’d be used 4 times? that’s not that bad, unless this function is called a lot).

As for the API, Following the template of texture scaling:
int SDL_SetTextureRotation(SDL_TextureID textureID, float degrees);
int SDL_GetTextureRotation(SDL_TextureID textureID, float* degrees);

Hello !

There is definitely a need for such a library for SDL (1.2)/1.3.
Maybe only for SDL 1.3, but as you will need to implement all the
functions in software too, maybe you can use it also for 1.2

My real concern is, all that should be in an external library
and not put into SDL itself, this would bloat it like Allegro.

SDL 1.3 should only contain a filling function itself for SDL 1.2 compat.
and for clearing the screen maybe, but anything like rotating sprites, drawing
lines, etc. should be external.

CU

How would you implement that? This is something that has to
be done at the texture level, which means the external library
would need to know the structure used to represent textures,
which SDL doesn’t provide for us, and it would need to be
done differently for each renderer.

Also, in OGL and D3D, rotation is an integral part of
drawing the quad; they aren’t two separate steps. Which
means your hypothetical external library would have to
duplicate a whole lot of code that’s already in SDL.

Really, this is better off as an internal part of the core
library.>----- Original Message ----

From: Torsten Giebl
Subject: Re: [SDL] Rotation API

Hello !

There is definitely a need for such a library for SDL (1.2)/1.3.
Maybe only for SDL 1.3, but as you will need to implement all the
functions in software too, maybe you can use it also for 1.2

My real concern is, all that should be in an external library
and not put into SDL itself, this would bloat it like Allegro.

SDL 1.3 should only contain a filling function itself for SDL 1.2 compat.
and for clearing the screen maybe, but anything like rotating sprites, drawing
lines, etc. should be external.

Mason Wheeler wrote:

How would you implement that? This is something that has to
be done at the texture level, which means the external library
would need to know the structure used to represent textures,
which SDL doesn’t provide for us, and it would need to be
done differently for each renderer.

Also, in OGL and D3D, rotation is an integral part of
drawing the quad; they aren’t two separate steps.

Really, this is better off as an internal part of the core
library.

I agree. It could work as part of an external library – as long as SDL doesn’t add any other rendering backends – but is much better as an integral part of the library.
Otherwise the library would also need to replace the functionality of SDL_RenderCopy.

[quote=“Mason Wheeler”]

Also, in OGL and D3D, rotation is an integral part of
drawing the quad; they aren’t two separate steps. Which
means your hypothetical external library would have to
duplicate a whole lot of code that’s already in SDL.

Really, this is better off as an internal part of the core
library.

[quote]

Agreed. One must remember that rotozoomSurface is an “offline renderer” taking software surface and producing another surface in some unspecified amount of time and not for real-time purposes. It is practical for SDL < 1.3 when all surfaces can be generated this way in load-time. With 1.3 and hw rendering rotation / scaling etc are integral parts of rendering pipeline and are no-cost features since rendered quads are transformed by world/camera/projection (depends of course) anyway. Is so just happens that for current SDL implementation default scaling factor is 1.0 and rotation is 0.0. Since it is possible to change scaling factor with SDL_SetTextureScaleMod it makes sense to simply add SDL_SetTextureRotationMod or whatever.

This is what I gather from a casual glance at the source.

Rotation would have to be implemented on the video level for each
driver that exists for SDL. Otherwise people not using D3D,OGL would
get left in the cold right?

Non-accelerated (no 3D/rotation/fancystuff) platforms fallback to
using the old SDL_surface internally, so they can all use the same
software based rotozoom, we see in SDL_gfx.

It sounds feasible. There enough games using features from SDL_gfx, so
people have already settled for less than sight blinding speeds.
Imagine if this were tightly integrated into a hardware accelerated
library. Given what we know about the past, this would probably be
godsend.

Small enough to go to into a small library, and used enough to be
worth keeping. Adding rotation doesn’t have to ruin portability.
Could even improve it.On Tue, Feb 23, 2010 at 6:38 AM, hardcoder wrote:

[quote=“Mason Wheeler”]

Also, in OGL and D3D, rotation is an integral part of
drawing the quad; they aren’t two separate steps. Which
means your hypothetical external library would have to
duplicate a whole lot of code that’s already in SDL.

Really, this is better off as an internal part of the core
library.

[quote]

Agreed. One must remember that rotozoomSurface is an "offline renderer"
taking software surface and producing another surface in some unspecified
amount of time and not for real-time purposes. It is practical for SDL < 1.3
when all surfaces can be generated this way in load-time. With 1.3 and hw
rendering rotation / scaling etc are integral parts of rendering pipeline
and are no-cost features since rendered quads are transformed by
world/camera/projection (depends of course) anyway. Is so just happens that
for current SDL implementation default scaling factor is 1.0 and rotation is
0.0. Since it is possible to change scaling factor with
SDL_SetTextureScaleMod it makes sense to simply add
SDL_SetTextureRotationMod or whatever.


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

Jeremiah wrote:

This is what I gather from a casual glance at the source.

Rotation would have to be implemented on the video level for each
driver that exists for SDL. Otherwise people not using D3D,OGL would
get left in the cold right?

Non-accelerated (no 3D/rotation/fancystuff) platforms fallback to
using the old SDL_surface internally, so they can all use the same
software based rotozoom, we see in SDL_gfx.

It sounds feasible. There enough games using features from SDL_gfx, so
people have already settled for less than sight blinding speeds.
Imagine if this were tightly integrated into a hardware accelerated
library. Given what we know about the past, this would probably be
godsend.

Small enough to go to into a small library, and used enough to be
worth keeping. Adding rotation doesn’t have to ruin portability.
Could even improve it.

Improve portability? I don’t know about that so much. I couldn’t see it harming portability either, though.
But certainly implementing in Direct3D and OpenGL is simple enough; and we’ve seen it done for the software renderer too.

This has come up several times and each time the real pain is the
software rendering. If someone is willing to step up and provide a
software implementation, I’m open to adding it.

My preference would be something like:
SDL_RenderCopyRotated(SDL_texture *texture, const SDL_Rect *srcrect,
const SDL_Rect * dstrect, int angle);

Whoever would implement the software side of this would probably have
to look at src/video/sdlgenblit.pl and add code to output rotating
versions of all those blitters.On Wed, Feb 17, 2010 at 12:02 PM, Mason Wheeler wrote:

I’ve seen a bunch of people asking about rotating and zooming and doing both
together on here. ?We’ve got the zooming working, now we need rotation. ?And
it doesn’t seem to me that that’s all that difficult, at least not for either OpenGL
or Direct3D.

The exact implementation details vary a bit, but in both systems, you render a
rectangular texture by specifying the locations of the four corners (vertices)
and associating the resulting quad it with a texture. ?Thing is, there’s no
requirement for the edges of your quad to be parallel to the edges of the
screen, or even for your quad to be rectangular at all.

Rotation, then, becomes trivial to anyone with a moderate knowledge of trig.
Input the original (unrotated) rectangle and an angle, calculate the
positions of the four vertices after applying the rotation, and send those to
GL/D3D.

How about something like this:

int SDL_RenderZoom(SDL_Texture * texture, const SDL_Rect * srcrect,
const SDL_Rect * dstrect, int angle);

Using int for the angle makes it easier to calculate this by using precomputed
sine and cosine tables. ?This could be made a float for extra precision if
anyone really cares about rotations smaller than 1/360 of a circle. ?The
center of the resulting quad would be the center of dstrect.

This would be more difficult to implement on non-accelerated backends, of
course. ?Perhaps it could be unimplemented, or fall back to something like
the rotozoom function on SDL_gfx.

This API would, of course, be much more useful in conjunction with render
targets.

Any thoughts?


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


-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

I would look at Sprig or SGE rotation for reference. From my experience,
it’s faster than SDL_gfx by a factor of about 1.3. The alpha-blended
primitives are faster, too.

Jonny D

Sam Lantinga wrote:

This has come up several times and each time the real pain is the
software rendering. If someone is willing to step up and provide a
software implementation, I’m open to adding it.

My preference would be something like:
SDL_RenderCopyRotated(SDL_texture *texture, const SDL_Rect *srcrect,
const SDL_Rect * dstrect, int angle);

Whoever would implement the software side of this would probably have
to look at src/video/sdlgenblit.pl and add code to output rotating
versions of all those blitters.

I don’t think this is the right way to go. When using hardware backend like D3D or OGL rotation (or scaling) may be considered a part of “blit” operation and is a no-cost thing.

On the other hand for software rendering it is the complete opposite and should not be encouraged on per-frame (or per-redraw / damaged rect) basis. That said, scaling and rotation operations should be used during the “blit” ONLY when using hw renderer. When using software mode, we are back to surfaces and all costly operations like scaling or rotation should be done at most once per many blits and ideally only once at load time.

Therefore I propose adding a field to SDL_RendererInfo structure to query renderer scaling/rotation capabilities.

hardcoder wrote:

Since it is possible to change scaling factor with SDL_SetTextureScaleMod it makes sense to simply add SDL_SetTextureRotationMod or whatever.

Sorry, obviously I made a mistake here, SDL_SettextureScaleMod is not for setting a scaling factor but a scaling algorithm. Please take no notice of this API proposal :wink:

There are a number of potential things like this rotation API and the
request for compressed texture support.

My feelings on this are: SDL should be as simple as possible. These
kind of enhancements, though cool, complicate the API and sometimes
cause issues because SDL still needs a software backend.

Rotation simply needs to be handled differently in software and
hardware modes, in software you probably want to pre-calculate all the
rotations to some degree of granularity at load time (depending on how
often the image will be rotated and at what angles). With a hardware
backend, there is no cost to the rotation so you can can specify any
angle at draw time.

I wonder would we be better to design an API that will expose the raw
texture handles to the world. Then someone can write an add on library
that supports all sorts of fancy operations like these (and more)
under the assumption that there will be a hardware accelerated
renderer. This way we can avoid bloating SDL with acceleration
specific features without limiting those who need them. Something not
unlike how we expose the raw window handles which allowed developers
implement desktop feature that didn’t make sense in a minimal library
like SDL. Advantages, SDL trades off a little safety in exposing these
handles while remaining a slimmer API overall. SDL places no
limitations on whatever the implementor of the SDL_Accel (or whatever)
library wants to offer in their API.

As I say this though, I am aware of the potential complexity and
brittleness of such a solution. Grabbing the window handle from SDL
was always a little bit of a hack.

Another (perhaps worse) idea would be something like OpenGL
extensions, where the video backend can provide optional
implementations of functionality like this, without providing any
fallbacks, software or otherwise. The user would retrieve a function
pointer using a string key, cast it to the correct signature and call
it. Its ugly, but allows for some interesting ideas for certain
backends (like the iPhone might have a function to change to landscape
or protrait co-ordinate systems). The advantage is that the code has
direct access to things like texture handles for the given backend,
the downside is the complexity on the callers side and that the
"bloat" (for some users) will be inside SDL.

Any opinions?

Remember, this is a proposal that applies to a whole slew of potential
functions that really only make sense for properly hardware
accelerated backend, not just for the examples of rotation and
compressed textures.On 24 February 2010 07:41, Sam Lantinga wrote:

This has come up several times and each time the real pain is the
software rendering. ?If someone is willing to step up and provide a
software implementation, I’m open to adding it.

My preference would be something like:
SDL_RenderCopyRotated(SDL_texture *texture, const SDL_Rect *srcrect,
const SDL_Rect * dstrect, int angle);

Whoever would implement the software side of this would probably have
to look at src/video/sdlgenblit.pl and add code to output rotating
versions of all those blitters.

2010/2/25 hardcoder

I don’t think this is the right way to go. When using hardware backend like D3D or OGL rotation (or scaling) may be considered a part of “blit” operation and is a no-cost thing.

On the other hand for software rendering it is the complete opposite and should not be encouraged on per-frame (or per-redraw / damaged rect) basis. That said, scaling and rotation operations should be used during the “blit” ONLY when using hw renderer. When using software mode, we are back to surfaces and all costly operations like scaling or rotation should be done at most once per many blits and ideally only once at load time.

Therefore I propose adding a field to SDL_RendererInfo structure to query renderer scaling/rotation capabilities.

This makes sense in a PC-level hardware environment. But I do have two
arguments against:

  1. It violates the principle of least surprise. Having per-frame
    rotations perform poorly in software mode is less surprising than not
    having them work at all. Which option is simpler for the end user to
    comprehend I leave open to debate.

  2. SDL is(/has been) also used in a variety of
    microcontroller/system-on-a-chip environments, many of which have
    neither HW acceleration nor enough memory to keep many prerendered
    rotations in memory. Of course those backends could do SW rotation on
    their own, but that would lead to needless duplication of code, and
    even more surprise! (Why does SW rotation work on chip X that has
    barely any processing power, but not on 6THz Pentium XXCVII with
    ATIVidia RadeonForce 999999USLSS? :wink: )

-Jukka-Pekka Manninen

I don’t think that’s necessarily the case at all. Doom had realtime
texture rotation (of the floors) in 1993. So long as you don’t go
overboard with the screen resolution, there’s no reason to expect that
realtime texture mapping wouldn’t work on modern computers.

Caching, on the other hand, consumes ridiculous amounts of memory.
Especially if you do it at load time instead of on demand. Even a
single 512x512 32bpp texture, well within the capabilities of a realtime
software texture mapper, would consume over a megabyte per pre-cached
rotation. Memory consumption could quickly reach gigabytes or even
terabytes.

Caching only works well when you’ve got a fairly small set of fairly
small sprites to rotate, and you don’t need a lot of smoothness.
Realtime rotation works well under a wider range of conditions, although
it is limited by fill rate.On 2/25/2010 09:51, Brian Barrett wrote:

Rotation simply needs to be handled differently in software and
hardware modes, in software you probably want to pre-calculate all the
rotations to some degree of granularity at load time (depending on how
often the image will be rotated and at what angles). With a hardware
backend, there is no cost to the rotation so you can can specify any
angle at draw time.


Rainer Deyke - rainerd at eldwood.com

There are a number of potential
things like this rotation API and the
request for compressed texture support.

My feelings on this are: SDL should be as simple as
possible. These
kind of enhancements, though cool, complicate the API and
sometimes
cause issues because SDL still needs a software backend.

You seem to have “simple” confused with "minimal."
SDL isn’t good because it can’t do very many things;
it’s good because it makes it simple (easy) for users
of the library to do the things they need. Not doing
things, especially things that the users need, is not
a virtue; it’s a deficiency.— On Thu, 2/25/10, Brian Barrett <brian.ripoff at gmail.com> wrote:

From: Brian Barrett <brian.ripoff at gmail.com>
Subject: Re: [SDL] Rotation API