textfiles/computers/DOCUMENTATION/bmscaler.txt

200 lines
9.6 KiB
Plaintext

#############################################################################
# #
# #### #### ### # ##### #### #
# # # # # # # # # #
# ### # ##### # ### # # #
# # # # # # # # # #
# #### #### # # ##### ##### #### #
# #
# #### ##### ##### ##### ### #### #### #
# # # # # # # # # # # # # #
# #### # # # # # ##### #### ### #
# # # # # # # # # # # # #
# #### ##### # # # # # # # #### #
# #
# Trainer #
# #
# by #
# #
# Tumblin / Bodies In Motion #
# #
#############################################################################
Hello there, this doc file is intended to be a trainer for doing
scaled bitmaps. The routines accompanying this file are not meant to be as
fast as possible, but clear and easy to learn what is going on when doing
this effect. With this in mind, lets put on our thinking caps and get our
hands dirty!
Okay, first a little bit of background theory. The basic algorithm
that my implementation of scaled bitmaps is based on is the infamous
Bresenham's Algorithm. This is the favoured technique for drawing lines
very quickly. But for scaled bitmaps, we modify it a little so that we can
take a column of pixels and stretch them out or squash them down. Lets go
through an example that we could use to draw a scaled bitmap, in the form of
a vertical column of pixels on the screen by taking pixel colors from a one
dimensional array.
The following pseudo code example will *stretch* a source bitmap to a larger
destination bitmap (a 64 pixel bitmap to a 124 pixel bitmap):
-----------------------------------------------------------------------------
source_height = 64
start_y = 0
end_y = 123
destination_height = end_y - start_y
error_term = 0
source_index = 0
screen_x = 0
screen_y = start_y
do
{
color=bitmap[source_index]
draw_pixel(screen_x,screen_y)
error_term = error_term + source_height
if error_term > destination_height
error_term = error_term - destination_height
source_index = source_index + 1
endif
screen_y = screen_y + 1
} while screen_y < end_y
-----------------------------------------------------------------------------
Here's the explanation.
In the do loop, you start out by grabbing a color from the source
bitmap that you want to scale onto the screen. You then draw that color on
the screen at the current screen coordinates. Then there is this error_term
thingy. What it is used for is to help us decide when it will be time to
change the index into the source bitmap so that we can pull out the next
color. What you do is you add the height of the source bitmap to the error
term, then you do a test to see if the error term has exceeded the size of
the destination bitmap. If it did, then you subtract the size of the
destination bitmap from the error term and also increase the index into the
source bitmap. After this decision is done, you increase the screen
coordinate. You keep repeating this do loop until the screen coordinate is
equal to the ending coordinate that you specified at the beginning. The
whole gist of scaling a small source bitmap to a larger destination bitmap is
to always increment the screen coordinate through each time through the loop
and only increment the index to the source bitmap when it is necessary to.
Every pixel in the source bitmap will be drawn at least once, even repeated
if need be. Just think in your mind that you are "stretching" the bitmap.
Pretty simple really.
Now here is what it would look like if you wanted to *shrink* a source bitmap
to a smaller destination bitmap (a 101 pixel bitmap to a 74 pixel bitmap):
-----------------------------------------------------------------------------
source_height = 101
start_y = 0
end_y = 73
destination_height = end_y - start_y
error_term = 0
source_index = 0
screen_x = 0
screen_y = start_y
do
{
color=bitmap[source_index]
draw_pixel(screen_x,screen_y)
error_term = error_term + destination_height
if error_term > source_height
error_term = error_term - source_height
screen_y = screen_y + 1
endif
source_index = source_index + 1
} while screen_y < end_y
-----------------------------------------------------------------------------
This is the same idea as before but with a few changes. In this one, you
grab a color from the source bitmap and draw it on the screen like in the
previous example. Then you add the size of the destination bitmap to the
error term. If the error term exceeds the size of the source bitmap then you
just subtract the size of the source bitmap from the error term and also
increment the screen coordinate. After the if statement, you manditorialy
increment the index into the source bitmap. So the gist of scaling a larger
source bitmap to a smaller destination bitmap is to always increment the
index into the source bitmap, but only drawing the pixels that are necessary.
This means that some of the pixels in the source bitmap will be skipped.
Now then, how do you scale a whole rectangular source bitmap to a
rectangular destination bitmap??? Well, you have to combine the techniques
above to take care both cases of drawing vertically stretched single columns
of pixels. Okay, so that takes care of drawing scaled vertical lines, but
what about the horizontal dimension? You basically use the same routines
explained above, but switch the x's with y's and use the index into the
source bitmap to select which column of the source bitmap you want to work
with and then use the very same routines that we used before. Actually
scaled bitmaps are nested Bresenham loops. Just remember that when you are
doing your routines, make sure you cover the two types of vertical scaling
(large to smaller, and small to larger), and the two types of horizontal
scaling (large to smaller and small to larger). Oops, actually there is one
more additional case, I forgot to mention the case where the source and
destination bitmaps are equal in size! But that is *easily* accounted for.
All you have to do is let one of the four cases also include an equality in
the sizes of both dimensions of the source and destination bitmaps. Another
thing to remember is that when you are done doing a vertical line, reset the
index to the source bitmap back to zero and reset the screen y coordinate to
the top again. All of this will be clear when you see the complete source
code ;-)
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Here are some tips for getting the code compiled:
My system consists of a 486DX 33MHz, Trident 8900 SVGA 1MB, 120MB hard drive,
Sound Blaster Pro, and I use Turbo C++ 3.0.
First you need a copy of XLIB06.ZIP
Unzip this file into a directory and then edit MAKEFILE to change the line
that says MODEL=s to MODEL=l (I used the large memory model to compile this
demo). This is what might have caused some people some confusion when they
tried to compile my previous release VECTBALL.ZIP. I included the
VECTBALL.PRJ file with it and I had the memmory model on the Large setting.
XLib 6 was released with the memory model set to Small. Please make sure
that the memory models match!
I might also mention that I also had to change the line that says CC=bcc to
CC=tcc (I compiled it with my Turbo C++ 3.0 and worked fine).
Next type MAKE and watch XLib 6 get compiled before your very eyes. When I
did it myself, I noticed some strange warnings fly up the screen, but they
didn't hurt anything one bit. I guess one of the demo programs didn't get
compiled, but the most important thing is that the XLIB6L.LIB file got
compiled okay.
Now you create a project file by typing BC BMSCALER.PRJ if you have the
Borland C++ 3.1 compiler or TC BMSCALER.PRJ if you have the Turbo C++ 3.0
compiler.
Next you add the BMSCALER.CPP and XLIB6L.LIB files into your project.
Use the Options/Code Generations option and select the Large memory model.
When you are done that, you should be all ready to compile the BMSCALER.CPP
by using Complile/Make, or compile it and run it in the IDE by doing a
Compile/Run.
Play around with the call to the bmscaler function and use some strange
coordinate combinations, they can make some pretty interesting visual effects.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
I guess that about wraps up my discussion on scaled bitmaps. If you have
any questions or comments, email me.
If you use this code in any demos you write, greet me, or send me a cool
post card from your country.
Tumblin / Bodies In Motion