abrash-black-book/50-01.md
2013-12-30 20:26:41 +11:00

131 lines
7.3 KiB
Markdown

Chapter 50\
Adding a Dimension {#Heading1}
-------------------
### 3-D Animation Using Mode X {#Heading2}
When I first started programming micros, more than 11 years ago now,
there wasn't much money in it, or visibility, or anything you could call
a promising career. Sometimes, it was a way to accomplish things that
would never have gotten done otherwise because minicomputer time cost
too much; other times, it paid the rent; mostly, though, it was just for
fun. Given free computer time for the first time in my life, I went
wild, writing versions of all sorts of software I had seen on
mainframes, in arcades, wherever. It was a wonderful way to learn how
computers work: Trial and error in an environment where nobody minded
the errors, with no meter ticking.
Many sorts of software demanded no particular skills other than a quick
mind and a willingness to experiment: Space Invaders, for instance, or
full-screen operating system shells. Others, such as compilers, required
a good deal of formal knowledge. Still others required not only
knowledge but also more horse-power than I had available. The latter I
filed away on my ever-growing wish list, and then forgot about for a
while.
Three-dimensional animation was the most alluring of the areas I passed
over long ago. The information needed to do rotation, projection,
rendering, and the like was neither so well developed nor widely so
available then as it is now, although, in truth, it seemed more
intimidating than it ultimately proved to be. Even had I possessed the
knowledge, though, it seems unlikely that I could have coaxed
satisfactory 3-D animation out of a 4 MHz Z80 system with 160x72
monochrome graphics. In those days, 3-D was pretty much limited to
outrageously expensive terminals attached to minis or mainframes.
Times change, and they seem to do so much faster in computer technology
than in other parts of the universe. A 486 is capable of decent 3-D
animation, owing to its integrated math coprocessor; not in the class
of, say, an i860, but pretty good nonetheless. A 386 is less
satisfactory, though; the 387 is no match for the 486's coprocessor, and
most 386 systems lack coprocessors. However, all is not lost; 32-bit
registers and built-in integer multiply and divide hardware make it
possible to do some very interesting 3-D animation on a 386 with
fixed-point arithmetic. Actually, it's possible to do a surprising
amount of 3-D animation in real mode, and even on lesser x86 processors;
in fact, the code in this article will perform real-time 3-D animation
(admittedly very simple, but nonetheless real-time and 3-D) on a 286
without a 287, even though the code is written in real-mode C and uses
floating-point arithmetic. In short, the potential for 3-D animation on
the x86 family is considerable.
With this chapter, we kick off an exploration of some of the sorts of
3-D animation that can be performed on the x86 family. Mind you, I'm
talking about real-time 3-D animation, with all calculations and drawing
performed on-the-fly. Generating frames ahead of time and playing them
back is an excellent technique, but I'm interested in seeing how far we
can push purely real-time animation. Granted, we're not going to make it
to the level of Terminator 2, but we should have some fun nonetheless.
The first few chapters in this final section of the book may seem pretty
basic to those of you experienced with 3-D programming, and, at the same
time, 3-D neophytes will inevitably be distressed at the amount of
material I skip or skim over. That can't be helped, but at least
there'll be working code, the references mentioned later, and some
explanation; that should be enough to start you on your way with 3-D.
Animating in three dimensions is a complex task, so this will be the
largest single section of the book, with later chapters building on
earlier ones; and even this first 3-D chapter will rely on polygon fill
and page-flip code from earlier chapters.
In a sense, I've saved the best for last, because, to my mind, real-time
3-D animation is one of the most exciting things of any stripe that can
be done with a computer—and because, with today's hardware, it can in
fact be done. Nay, it can be done amazingly well.
### References on 3-D Drawing {#Heading3}
There are several good sources for information about 3-D graphics. Foley
and van Dam's *Computer Graphics: Principles and Practice* (Second
Edition, Addison-Wesley, 1990) provides a lengthy discussion of the
topic and a great many references for further study. Unfortunately, this
book is heavy going at times; a more approachable discussion is provided
in *Principles of Interactive Computer Graphics*, by Newman and Sproull
(McGraw-Hill, 1979). Although the latter book lacks the last decade's
worth of graphics developments, it nonetheless provides a good overview
of basic 3-D techniques, including many of the approaches likely to work
well in realtime on a PC.
A source that you may or may not find useful is the series of six books
on C graphics by Lee Adams, as exemplified by *High-Performance CAD
Graphics in C* (Windcrest/Tab, 1986). (I don't know if all six books
discuss 3-D graphics, but the four I've seen do.) To be honest, this
book has a number of problems, including: Relatively little theory and
explanation; incomplete and sometimes erroneous discussions of graphics
hardware; use of nothing but global variables, with cryptic names like
"array3" and "B21;" and—well, you get the idea. On the other hand, the
book at least touches on a great many aspects of 3-D drawing, and
there's a lot of C code to back that up. A number of people have spoken
warmly to me of Adams' books as their introduction to 3-D graphics. I
wouldn't recommend these books as your only 3-D references, but if
you're just starting out, you might want to look at one and see if it
helps you bridge the gap between the theory and implementation of 3-D
graphics.
### The 3-D Drawing Pipeline {#Heading4}
Each 3-D object that we'll handle will be built out of polygons that
represent the surface of the object. Figure 50.1 shows the stages a
polygon goes through enroute to being drawn on the screen. (For the
present, we'll avoid complications such as clipping, lighting, and
shading.) First, the polygon is transformed from object space, the
coordinate system the object is defined in, to world space, the
coordinate system of the 3-D universe. Transformation may involve
rotating, scaling, and moving the polygon. Fortunately, applying the
desired transformation to each of the polygon vertices in an object is
equivalent to transforming the polygon; in other words, transformation
of a polygon is fully defined by transformation of its vertices, so it
is not necessary to transform every point in a polygon, just the
vertices. Likewise, transformation of all the polygon vertices in an
object fully transforms the object.
Once the polygon is in world space, it must again be transformed, this
time into view space, the space defined such that the viewpoint is at
(0,0,0), looking down the Z axis, with the Y axis straight up and the X
axis off to the right. Once in view space, the polygon can be
perspective-projected to the screen, with the projected X and Y
coordinates of the vertices finally being used to draw the polygon.
That's really all there is to basic 3-D drawing: transformation from
object space to world space to view space to the screen. Next, we'll
look at the mechanics of transformation.