I’d been putting off moving from wireframe rendering to filled polygons because I was worried about what was going to happen to my framerate, but now that I’ve finally bit the bullet it’s not nearly as big a deal as I thought it would be. That’s another advantage of the Amiga’s Blitter: it does all the work, and I take all the credit.
As I understand it, here’s what happens when you use the graphics.library’s filled polygon routines:
- The program calls AreaMove() to begin the polygon and give the location of the first vertex in screen coordinates. It then calls AreaDraw() for each remaining vertex, and then AreaEnd() when it’s done.
- The vertex coordinates are stored in a temporary buffer called AreaInfo attached to the screen’s RastPort.
- The blitter is used to draw the outline of the polygon into a temporary buffer called TmpRas, also attached to the screen’s RastPort.
- The rectangle containing the polygon is copied into one or more bitplanes of the screen buffer using a special fill mode. For each row, the Blitter scans until it hits the outline, and then writes fill bits until it hits the outline on the other side of the polygon. (The fill bits can be turned on and off multiple time per row, so that this can be used to fill in concave polygons).
The Blitter is very flexible and can perform a variety of logical operations on its inputs, apply mask inputs, and so on. I’ve really only scratched the surface. In this case, it’s figuring out how to fill in an arbitrary polygon for the price of copying a rectangle between two bitplanes, which is a pretty good deal.
Once I’d replaced my wireframe cube with a solid version, I started playing with the graphics again. I used some tricks with the palette to make the cube look partially transparent. I’m using three bitplanes now, with the different-colored sides of the cube drawn in bitplanes 0 and 2, and the background elements drawn in plane 1. The palette looks like this:
Color # Description 0 Background land and sky 1 Red surfaces of cube 2 Background details (pyramids, moon, stars) 3 Background details behind red side 4 Green surface of cube 5 Blue surface of cube 6 Background details behind green side 7 Background details behind blue side
If I want the cube to appear solid, I just need to make color 1 the same as 3, 4 the same as 6, and 5 the same as 7. Make any pair different shades, and the background will “show through”.
I also used the copper to change the actual color values at various positions, so that the cube colors are pale when it’s in front of the moon and darker when it’s in front of the pyramid, and so that the ground color seen through the cube fades the same way it does without the cube in the way. It’s a fake, and doesn’t entirely make sense because the rear faces of the cube aren’t drawn, but it’s still pretty convincing looking.
I also decided that I was tired of seeing that cube spinning in one place, so I played with its animation a bit. I’ve now got it orbiting around the origin, coming closer to and then farther away from the camera.
Finally, I decided to add another shape back in. I’ve got to wrap this project up in a couple days because I’m leaving for Gen Con on Wednesday, so in honor of that I added an icosahedron – the iconic shape of a twenty-sided die.
The icosahedron puts a lot more load on the CPU than the cube does: 20 faces versus 6, 12 vertices versus 8. It cuts my framerate in half, as you can tell from the video. I’m getting 20+ fps from the cube, and just over 10 fps when the icosahedron is onscreen.