[AD] Optimized rotation routine

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Hello!
I have rewritten Allegro's rotation routine so it's
now usually at least 3 times faster (and in some cases
more: the extremest case is a 1x5792 bitmap rotated 45
degrees, which is about 350 times faster :-). It also
has better accuracy: the old routine was usually
several pixels wrong due to rounding errors. But
before I post a patch I'd like to know how much I
should change (I uploaded the current version (which
needs some polishing) to
http://www.geocities.com/ssven.geo/misc/rotation.html).
The issue is that the new routine is more generic than
the old -- it can map a sprite to an arbitrary
parallelogram using an arbitrary scanline drawer -- so
there is a possibility to add new API entries. The
following would be possible to add:

 (1) Support solid mode, i.e. don't skip transparent
pixels.
 (2) `parallelogram_map()', the lowest level (most
generic) function that maps a sprite to an arbitrary
parallelogram using an arbitrary scanline drawer.
 (3) The second lowest level function, which is like
(2) but with the default scanline drawer.
 (4) `rotate_scale_flip_coordinates()', which takes a
rotation angle, a scaling factor, pivot coordinates,
and x and y coordinates, and calculates the corners of
the corresponding parallelogram, ready to be passed to
the lower level functions.
 (5) Functions for scaling x and y differently, ie.
like first doing a stretch_sprite() and then rotating.
 (6) Functions with sub-pixel accuracy on the x and y
coordinates.
 (7) This isn't a new API call, but it's new
functionality: We could remove all restrictions on
source and dest, so that you could map from any screen
bitmaps and between different color depths. So it's
almost as generic as  `blit()' (except it can't handle
overlapping areas, of course).

All these are easy to add, it's at most a matter of
writing a wrapper.

I would propose the following, based on the assumption
that I'm going to write an add-on library to do
anti-aliased rotation which needs access to the lowest
level function:

 (1) Don't include it: It would double the number of
API entries and I have never seen anyone asking for
this functionality. It would be easy for an add-on
library to do this anyway.
 (2) Include it in internal.h: It would be useful for
add-ons that do anti-aliased drawing, so they only
need to provide scanline drawers.
 (3) Include it in allegro.h: This function is
necessary and sufficient for mapping a sprite to a
parallelogram using the default scanline drawers, and
I think it would be a pity not to give access to it.
 (4) Include it in internal.h: Any add-on library will
need this function. A normal user could actually also
need it to calculate the bounding box of a rotated
sprite (eg. for doing dirty rectangle animation), but
I think it's too obscure to put in allegro.h.
 (5) Don't include them: It can be done with either
(3) or (4)+(2) anyway, or by an add-on library.
 (6) Don't include them: An add-on library could do it
instead.
 (7) Include it: it doesn't add anything to the API,
so it can hardy hurt, can it? It would just require
one more scanline drawer.

What do you think?

Also, the old version flips the sprite when scale<0:
is this a feature or a bug? I.e. should I also make it
flip or should I make it return without drawing
anything?

I also have a technical question: The old version
checks if a pixel is transparent by comparing it with
`bmp->vtable->mask_color'. Is there any reason not to
use the MASK_COLOR_* constant, ie. can they be
different? It's of course much faster to use the
constant.

Sven

__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail
http://personal.mail.yahoo.com/



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/