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-
comments to---> phkahler@oakland.edu
|