View this PageEdit this PageAttachments to this PageHistory of this PageHomeRecent ChangesSearch the SwikiHelp Guide
Hotspots: Admin Pages | Turn-in Site |
Current Links: Cases Final Project Summer 2007

Fading Images, the BitBlt Approach

So you want fading images? You may have seen the many #fadeImage— methods
that the class Form has. Well I dont know what those do or how to use them so
if you do please edit this. So I went looking for alternate ways to fade images.
But before we get into that you need to make sure your Squeak image is setup
correctly. The display depth needs to be set to 32 bits, this can be done from the
World > appearance > display depth menu or programatically by running:
   Display newDepth: 32.

I found two ways to achieve the effect I wanted with the Forms in Squeak that
represent images. The first is the Form message #pixelValueAt:put:, you can
iterate through every pixel in the Form and modify the color changing its alpha
value and voila! some thousands of message sends later you have a faded image.
I tried this myself at first but it is dreadfully slow, so on to method two.

Squeak has a BitBlt class that works similarly to BitBlt operations found in many
graphics packages. What this class is used for is copying an area of pixels from
one Form onto another, the pixels from the source Form are combined with those
of the destination Form by a combination rule. This may sound a bit abstract but it
is the key to fading images given the correct source Form and combination rule.
It is also much quicker than the first method because it uses an underlying primitive.
I reccomend reading the class comment for the BitBlt class which provides a thorough
explanation of the BitBlt capabilities in Squeak.

So now let me explain the exact procedure and give you an example. We are going
to need some image to fade which I'll call anImage and 2 temporary variables,
the BitBlt object and the source Form, which I'll declare now:
   | alphaBlit alphaForm |

Now we need to make our source Form with the alpha transparency that we want our
image to get. So we create a basic Form with depth of 32 and the extent of the anImage
we are fading and then fill it with a Color that has the just the desired alpha transparency
we want our images to have and no red green or blue values. Alpha transparency is
represented by a floating point value from 0.0 (no transparency) to 1.0 (fully transparent),
I'll use 50% trasparency below:
   alphaForm := Form extent: (originalForm extent) depth: 32.
   alphaForm fillColor: (Color r: 0.0 g: 0.0 b: 0.0 alpha: 0.5).

Next we can create our BitBlt object using the Form we just created and anImage as follows.
   alphaBlit := BitBlt
		destForm: anImage
		sourceForm: alphaForm
		fillColor: Color yellow "any Color but Color transparent"
		combinationRule: 4 "rule that gets a transparent effect"
		destOrigin: 0@0
		sourceOrigin: 0@0
		extent: (anImage extent)
		clipRect: (anImage boundingBox).

Now we are pretty much done and we only need to apply what we have set up by sending the
following message:
   alphaBlit copyBits.

anImage should now be 50% transparent, to view it open it in the World as a SketchMorph:
   (SketchMorph withForm: anImage) openInWorld.

There are many other possible uses of BitBlt besides fading depending on what forms and
combination rules are used, experimentating with BitBlt can provide interesting results.

For an actual implementation you can see the DeadCreature and FoodPellet classes in our
Milestone 5 code (Team RAR). The DeadCreature floats to the top of our tank and then fades
away, the FoodPellet floats to the bottom and fades away, both using the above technique.

External Resources - provides a good explanation of BitBlt

Link to this Page