Информационный сервер для программистов: Исходники со всего света. Паскальные исходники со всего света
  Powered by Поисковый сервер Яndex: Найдется ВСЁ!
На Главную Pascal Форум Информер Страны мира
   Графика    >>    rotate
   
 
 Bitmap Scaling and Rotating for Mode $13   Paul H. Kahler 03.02.1994

Быстрое вращение, сдвиг и масштабирование изображений.
Examples of a fast method for rotating/panning/scaling bitmaps.



17k 
 

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