Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
99
52-08.md
Normal file
99
52-08.md
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[Previous](52-07.html) [Table of Contents](index.html) [Next](53-01.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
The keys to the performance increase manifested in this chapter’s code
|
||||
are three. The first key is fixed-point arithmetic. In the previous two
|
||||
chapters, we worked with floating-point coordinates and transformation
|
||||
matrices. Those values are now stored as 32-bit fixed-point numbers, in
|
||||
the form 16.16 (16 bits of whole number, 16 bits of fraction). 32-bit
|
||||
fixed-point numbers allow sufficient precision for 3-D animation, but
|
||||
can be manipulated with fast integer operations, rather than by slow
|
||||
floating-point processor operations or excruciatingly slow
|
||||
floating-point emulator operations. Although the speed advantage of
|
||||
fixed-point varies depending on the operation, on the processor, and on
|
||||
whether or not a coprocessor is present, fixed-point multiplication can
|
||||
be as much as 100 times faster than the emulated floating-point
|
||||
equivalent. (I’d like to take a moment to thank Chris Hecker for his
|
||||
invaluable input in this area.)
|
||||
|
||||
The second performance key is the use of the 386’s native 32-bit
|
||||
multiply and divide instructions. C compilers operating in real mode
|
||||
call library routines to perform multiplications and divisions involving
|
||||
32-bit values, and those library functions are fairly slow, especially
|
||||
for division. On a 386, 32-bit multiplication and division can be
|
||||
handled with the bit of code in Listing 52.9—and most of even that code
|
||||
is only for rounding.
|
||||
|
||||
The third performance key is maintaining and operating on only the
|
||||
relevant portions of transformation matrices and coordinates. The bottom
|
||||
row of every transformation matrix we’ll use (in this book) is [0 0 0
|
||||
1], so why bother using or recalculating it when concatenating
|
||||
transforms and transforming points? Likewise for the fourth element of a
|
||||
3-D vector in homogeneous coordinates, which is always 1. Basically,
|
||||
transformation matrices are treated as consisting of a 3x3 rotation
|
||||
matrix and a 3x1 translation vector, and coordinates are treated as 3x1
|
||||
vectors. This saves a great many multiplications in the course of
|
||||
transforming each point.
|
||||
|
||||
Just for fun, I reimplemented the animation of Listings 52.1 through
|
||||
52.10 with floating-point instructions. Together, the preceeding
|
||||
optimizations improve the performance of the entire animation—including
|
||||
drawing time and overhead, and not just math—by more than ten times over
|
||||
the code that uses the floating-point emulator. Amazing what one can
|
||||
accomplish with a few dozen lines of assembly and a switch in number
|
||||
format, isn’t it? Note that no assembly code other than the native 386
|
||||
multiply and divide is used in Listings 52.1 through 52.10, although the
|
||||
polygon fill code is of course mostly in assembly; we’ve achieved 12
|
||||
cubes animated at 15 fps while doing the 3-D work almost entirely in
|
||||
Borland C++, and we’re *still* doing sine and cosine via the
|
||||
floating-point emulator. Happily, we’re still nowhere near the upper
|
||||
limit on the animation potential of the PC.
|
||||
|
||||
#### Drawbacks {#Heading6}
|
||||
|
||||
The techniques we’ve used to turbocharge 3-D animation are very
|
||||
powerful, but there’s a dark side to them as well. Obviously, native 386
|
||||
instructions won’t work on 8088 and 286 machines. That’s rectifiable;
|
||||
equivalent multiplication and division routines could be implemented for
|
||||
real mode and performance would still be reasonable. It sure is nice to
|
||||
be able to plug in a 32-bit **IMUL** or **DIV** and be done with it,
|
||||
though. More importantly, 32-bit fixed-point arithmetic has limitations
|
||||
in range and accuracy. Points outside a 64Kx64Kx64K space can’t be
|
||||
handled, imprecision tends to creep in over the course of multiple
|
||||
matrix concatenations, and it’s quite possible to generate the dreaded
|
||||
divide by 0 interrupt if Z coordinates with absolute values less than
|
||||
one are used.
|
||||
|
||||
I don’t have space to discuss these issues in detail, but here are some
|
||||
brief thoughts: The working 64Kx64Kx64K fixed-point space can be paged
|
||||
into a larger virtual space. Imprecision of a pixel or two rarely
|
||||
matters in terms of display quality, and deterioration of concatenated
|
||||
rotations can be corrected by restoring orthogonality, for example by
|
||||
periodically calculating one row of the matrix as the cross-product of
|
||||
the other two (forcing it to be perpendicular to both). Alternatively,
|
||||
transformations can be calculated from scratch each time an object or
|
||||
the viewer moves, so there’s no chance for cumulative error. 3-D
|
||||
clipping with a front clip plane of -1 or less can prevent divide
|
||||
overflow.
|
||||
|
||||
#### Where the Time Goes {#Heading7}
|
||||
|
||||
The distribution of execution time in the animation code is no longer
|
||||
wildly biased toward transformation, but sine and cosine are certainly
|
||||
still sucking up cycles. Likewise, the overhead in the calls to
|
||||
**FixedMul()** and **FixedDiv()** is costly. Much of this is correctable
|
||||
with a little carefully crafted assembly language and a lookup table;
|
||||
I’ll provide that shortly.
|
||||
|
||||
Regardless, with this chapter we have made the critical jump to a usable
|
||||
level of performance and a serviceable general-purpose framework. From
|
||||
here on out, it’s the fun stuff.
|
||||
|
||||
------------------------ --------------------------------- --------------------
|
||||
[Previous](52-07.html) [Table of Contents](index.html) [Next](53-01.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
* * * * *
|
||||
|
||||
Graphics Programming Black Book © 2001 Michael Abrash
|
||||
Loading…
Reference in a new issue