Replace invalid characters with HTML entities

— with —
’ with ’
+ with +
× with x
ç with ç
“ with “
” with ”
‘ with ‘
• with •
– with -
µ with µ
† with †
Fix C++
θ with θ
Yen symbol instead of times
Fix broken apos
Bullet again
E-circumflex
This commit is contained in:
James Gregory 2013-12-30 12:50:32 +11:00
commit 500e7f5654
353 changed files with 5091 additions and 5091 deletions

View file

@ -39,15 +39,15 @@
<H2><A NAME="Heading1"></A><FONT COLOR="#000077">Chapter 54<BR>3-D Shading
</FONT></H2>
<H3><A NAME="Heading2"></A><FONT COLOR="#000077">Putting Realistic Surfaces on Animated 3-D Objects</FONT></H3>
<P>At the end of the previous chapter, X-Sharp had just acquired basic hidden-surface capability, and performance had been vastly improved through the use of fixed-point arithmetic. In this chapter, we&#146;re going to add quite a bit more: support for 8088 and 80286 PCs, a general color model, and shading. That&#146;s an awful lot to cover in one chapter (actually, it&#146;ll spill over into the next chapter), so let&#146;s get to it!
<P>At the end of the previous chapter, X-Sharp had just acquired basic hidden-surface capability, and performance had been vastly improved through the use of fixed-point arithmetic. In this chapter, we&rsquo;re going to add quite a bit more: support for 8088 and 80286 PCs, a general color model, and shading. That&rsquo;s an awful lot to cover in one chapter (actually, it&rsquo;ll spill over into the next chapter), so let&rsquo;s get to it!
</P>
<H3><A NAME="Heading3"></A><FONT COLOR="#000077">Support for Older Processors</FONT></H3>
<P>To date, X-Sharp has run on only the 386 and 486, because it uses 32-bit multiply and divide instructions that sub-386 processors don&#146;t support. I chose 32-bit instructions for two reasons: They&#146;re much faster for 16.16 fixed-point arithmetic than any approach that works on the 8088 and 286; and they&#146;re much easier to implement than any other approach. In short, I was after maximum performance, and I was perhaps just a little lazy.
<P>To date, X-Sharp has run on only the 386 and 486, because it uses 32-bit multiply and divide instructions that sub-386 processors don&rsquo;t support. I chose 32-bit instructions for two reasons: They&rsquo;re much faster for 16.16 fixed-point arithmetic than any approach that works on the 8088 and 286; and they&rsquo;re much easier to implement than any other approach. In short, I was after maximum performance, and I was perhaps just a little lazy.
</P>
<P>I should have known better than to try to sneak this one by you. The most common feedback I&#146;ve gotten on X-Sharp is that I should make it support the 8088 and 286. Well, I can take a hint as well as the next guy. Listing 54.1 is an improved version of FIXED.ASM, containing dual 386/8088 versions of <B>CosSin(), XformVec()</B>, and <B>ConcatXforms()</B>, as well as <B>FixedMul()</B> and <B>FixedDiv()</B>.</P>
<P>Given the new version of FIXED.ASM, with <B>USE386</B> set to 0, X-Sharp will now run on any processor. That&#146;s not to say that it will run fast on any processor, or at least not as fast as it used to. The switch to 8088 instructions makes X-Sharp&#146;s fixed-point calculations about 2.5 times slower overall. Since a PC is perhaps 40 times slower than a 486/33, we&#146;re talking about a hundred-times speed difference between the low end and mainstream. A 486/33 can animate a 72-sided ball, complete with shading (as discussed later), at 60 frames per second (fps), with plenty of cycles to spare; an 8-MHz AT can animate the same ball at about 6 fps. Clearly, the level of animation an application uses must be tailored to the available CPU horsepower.</P>
<P>The implementation of a 32-bit multiply using 8088 instructions is a simple matter of adding together four partial products. A 32-bit divide is not so simple, however. In fact, in Listing 54.1 I&#146;ve chosen not to implement a full 32&#215;32 divide, but rather only a 32&#215;16 divide. The reason is simple: performance. A 32&#215;16 divide can be implemented on an 8088 with two <B>DIV</B> instructions, but a 32&#215;32 divide takes a great deal more work, so far as I can see. (If anyone has a fast 32&#215;32 divide, or has a faster way to handle signed multiplies and divides than the approach taken by Listing 54.1, please drop me a line care of the publisher.) In X-Sharp, division is used only to divide either X or Y by Z in the process of projecting from view space to screen space, so the cost of using a 32&#215;16 divide is merely some inaccuracy in calculating screen coordinates, especially when objects get very close to the Z = 0 plane. This error is not cumulative (that is, it doesn&#146;t carry over to later frames), and in my experience doesn&#146;t cause noticeable image degradation; therefore, given the already slow performance of the 8088 and 286, I&#146;ve opted for performance over precision.</P>
<P>At any rate, please keep in mind that the non-386 version of <B>FixedDiv()</B> is <I>not</I> a general-purpose 32&#215;32 fixed-point division routine. In fact, it will generate a divide-by-zero error if passed a fixed-point divisor between -1 and 1. As I&#146;ve explained, the non-386 version of <B>Fixed-Div()</B> is designed to do just what X-Sharp needs, and no more, as quickly as possible.</P><P><BR></P>
<P>I should have known better than to try to sneak this one by you. The most common feedback I&rsquo;ve gotten on X-Sharp is that I should make it support the 8088 and 286. Well, I can take a hint as well as the next guy. Listing 54.1 is an improved version of FIXED.ASM, containing dual 386/8088 versions of <B>CosSin(), XformVec()</B>, and <B>ConcatXforms()</B>, as well as <B>FixedMul()</B> and <B>FixedDiv()</B>.</P>
<P>Given the new version of FIXED.ASM, with <B>USE386</B> set to 0, X-Sharp will now run on any processor. That&rsquo;s not to say that it will run fast on any processor, or at least not as fast as it used to. The switch to 8088 instructions makes X-Sharp&rsquo;s fixed-point calculations about 2.5 times slower overall. Since a PC is perhaps 40 times slower than a 486/33, we&rsquo;re talking about a hundred-times speed difference between the low end and mainstream. A 486/33 can animate a 72-sided ball, complete with shading (as discussed later), at 60 frames per second (fps), with plenty of cycles to spare; an 8-MHz AT can animate the same ball at about 6 fps. Clearly, the level of animation an application uses must be tailored to the available CPU horsepower.</P>
<P>The implementation of a 32-bit multiply using 8088 instructions is a simple matter of adding together four partial products. A 32-bit divide is not so simple, however. In fact, in Listing 54.1 I&rsquo;ve chosen not to implement a full 32x32 divide, but rather only a 32x16 divide. The reason is simple: performance. A 32x16 divide can be implemented on an 8088 with two <B>DIV</B> instructions, but a 32x32 divide takes a great deal more work, so far as I can see. (If anyone has a fast 32x32 divide, or has a faster way to handle signed multiplies and divides than the approach taken by Listing 54.1, please drop me a line care of the publisher.) In X-Sharp, division is used only to divide either X or Y by Z in the process of projecting from view space to screen space, so the cost of using a 32x16 divide is merely some inaccuracy in calculating screen coordinates, especially when objects get very close to the Z = 0 plane. This error is not cumulative (that is, it doesn&rsquo;t carry over to later frames), and in my experience doesn&rsquo;t cause noticeable image degradation; therefore, given the already slow performance of the 8088 and 286, I&rsquo;ve opted for performance over precision.</P>
<P>At any rate, please keep in mind that the non-386 version of <B>FixedDiv()</B> is <I>not</I> a general-purpose 32x32 fixed-point division routine. In fact, it will generate a divide-by-zero error if passed a fixed-point divisor between -1 and 1. As I&rsquo;ve explained, the non-386 version of <B>Fixed-Div()</B> is designed to do just what X-Sharp needs, and no more, as quickly as possible.</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>