The file you've unzipped contains 2 executable programs and the complete
source code for each. The programs are meant to be examples of a fast method
for rotating bitmaps. I came up with the method on my own. Though I'm sure
it has been used before by other people, I've never seen it talked about or
presented by anyone else.
BITMAP.EXE -- This program pans/scales/rotates a 256x256 bitmap which is
tiled over the whole screen. Though it uses 320x200 mode (13h) it maintains
a 1:1 aspect ratio. The source is fully commented and meant for people to
learn from. It is written in Turbo Pascal with some inline assembly, but
C programmers should be able to make good sense of it. The test bitmap
created by the program is stupid, but it does show what can happen to certain
types of images when they are scaled down. If anyone throws in code to load
a standard image file please let me know.
TILE.EXE -- This one does basically the same thing, only it uses a 32x32
bitmap defined in the source which can be easily altered by anyone with
the compiler. There are NO comments and the aspect ratio is not correct.
The code is not well optimized, so it's slower.
Overview of rotation methods:
-----------------------------
I've heard a lot of people ask how to rotate a bitmap, and there seem to
be a few common methods that get brought up:
1) Scan the source image pixel by pixel. For each one, transform the
coordinates (with a rotation matrix or whatever) and plot the pixel
at these new coordinates in the destination image. This method produces
bad images with holes, because not all pixels in the destination image
get written to.
2) Scan the destination image pixel by pixel and 'untransform' (ie. rotate
the opposite direction) the coordinates of the pixel and use the new
coordinates to grab a pixel from the source image and copy it to the
destination. This prevent the 'holes' from appearing, because EVERY
pixel in the destination is mapped to something in the source image.
3) Do 3 shear operations. Shearing a rectangular bitmap will turn it into
a parallelogram. You can achieve a rotation by performing 3 shear
operations on it. This is often given (as of this writing) as a good way
to do it, but I never tried. #4 is just plain faster.
4) The method used by these programs is to scan the destination image
left to right/top to bottom, and at the same time scan the source image
by using rotated 'right' and 'down' vectors. This can be done extremely
fast by using fixed point math for the vectors and coordinates, and
eliminates the need to do any transformations. This method is faster than
the others and produces no holes in the destination image. It also allows
easy scaling of the bitmap at the same time (as do the other methods).
Sprites:
--------
Most people want to rotate sprites, not do what these programs do. If you
understand the code, you can see that it isn't hard to adapt it to draw
sprites. I recommend storing them in a 256-wide image, so the 8.8 fixed
point calculations can be preserved. So what if thats wider than your
sprite... Put a couple side by side in the image. Also, the inner
loop will have to be modified so that it won't write the 'clear' parts
of the sprite to the destination image. This can be done by adding 2
instructions to the inner loop like so:
mov bl,[ds:bx]
or bl,bl
jz nodraw <-- Add these 2 instructions
mov [es:di],bl <-- and label the 'inc' instruction
nodraw: inc di
This will slow things down a bit, but for actually doing sprites you'll
want to have it branch when it IS drawing a pixel, since that will probably
happen LESS often. (a 16x16 sprite requires scaning a 27x27 pixel area to
allow full rotation, and this extra area will all be clear.)
I hope all this helps someone. I've already started writing a game with it
and I can think of a few more that would be cool.
Paul H. Kahler
comments to---> phkahler@oakland.edu
|