diff --git a/01-01.md b/01-01.md index 47cee25..9a3b828 100644 --- a/01-01.md +++ b/01-01.md @@ -1,7 +1,3 @@ - ------------------------------- --------------------------------- -------------------- - [Previous](about_author.html) [Table of Contents](index.html) [Next](01-02.html) - ------------------------------- --------------------------------- -------------------- - *Part I* {align="center"} -------- @@ -114,12 +110,4 @@ with just a little thought. As we'll see, handcrafted assembly language and optimizing compilers matter, but less than you might think, in the grand scheme of things—and they scarcely matter at all unless they're used in the context of a good design and a thorough understanding of -both the task at hand and the PC. - - ------------------------------- --------------------------------- -------------------- - [Previous](about_author.html) [Table of Contents](index.html) [Next](01-02.html) - ------------------------------- --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +both the task at hand and the PC. \ No newline at end of file diff --git a/01-02.md b/01-02.md index 9feb1de..b8e997f 100644 --- a/01-02.md +++ b/01-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](01-01.html) [Table of Contents](index.html) [Next](01-03.html) - ------------------------ --------------------------------- -------------------- - ### Rules for Building High-Performance Code {#Heading5} We've got the following rules for creating high-performance software: @@ -135,12 +131,4 @@ together are equivalent to Listing 1.1 except that the entire checksum loop is written in tight assembly code. The assembly language implementation is indeed faster than any of the C versions, as shown in Table 1.1, but it's less than 10 percent faster, and it's still -unacceptably slow. - - ------------------------ --------------------------------- -------------------- - [Previous](01-01.html) [Table of Contents](index.html) [Next](01-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +unacceptably slow. \ No newline at end of file diff --git a/01-03.md b/01-03.md index 4cfc32a..db0be1f 100644 --- a/01-03.md +++ b/01-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](01-02.html) [Table of Contents](index.html) [Next](01-04.html) - ------------------------ --------------------------------- -------------------- - * * * * * Listing @@ -251,12 +247,4 @@ Listing 1.1, *even though Listing 1.1 and Listing 1.4 look almost the same*. To the casual observer, **read()** and **getc()** would seem slightly different but pretty much interchangeable, and yet in this application the performance difference between the two is about the same -as that between a 4.77 MHz PC and a 16 MHz 386. - - ------------------------ --------------------------------- -------------------- - [Previous](01-02.html) [Table of Contents](index.html) [Next](01-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +as that between a 4.77 MHz PC and a 16 MHz 386. \ No newline at end of file diff --git a/01-04.md b/01-04.md index 9e6f6d2..c0ebe65 100644 --- a/01-04.md +++ b/01-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](01-03.html) [Table of Contents](index.html) [Next](01-05.html) - ------------------------ --------------------------------- -------------------- - ------------------- -------------------------------------------------------------------------------------------------------------------------------------------------- ![](images/i.jpg) *Make sure you understand what really goes on when you insert a seemingly-innocuous function call into the time-critical portions of your code.* ------------------- -------------------------------------------------------------------------------------------------------------------------------------------------- @@ -116,12 +112,4 @@ does *not* run fast enough—13 seconds is a long time. (Stop and wait for long it is.) The second reason is the hallmark of the mediocre programmer. Know when -optimization matters—and then optimize when it does! - - ------------------------ --------------------------------- -------------------- - [Previous](01-03.html) [Table of Contents](index.html) [Next](01-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +optimization matters—and then optimize when it does! \ No newline at end of file diff --git a/01-05.md b/01-05.md index 50b4503..f8a3400 100644 --- a/01-05.md +++ b/01-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](01-04.html) [Table of Contents](index.html) [Next](01-06.html) - ------------------------ --------------------------------- -------------------- - The third reason is often fallacious. C library functions are not always written in assembly, nor are they always particularly well-optimized. (In fact, they're often written for *portability*, which has nothing to @@ -164,11 +160,3 @@ the design has been maxed out. printf("The checksum is: %u\n", Checksum); exit(0); } - - ------------------------ --------------------------------- -------------------- - [Previous](01-04.html) [Table of Contents](index.html) [Next](01-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/01-06.md b/01-06.md index d8f77a0..3caa72c 100644 --- a/01-06.md +++ b/01-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](01-05.html) [Table of Contents](index.html) [Next](02-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 1.7 L1-7.ASM** ; Assembler subroutine to perform a 16-bit checksum on a block of @@ -110,12 +106,4 @@ be sped up. I'm going to focus on specific ways to create high-performance code from now on. In Chapter 5, we'll continue to look at restartable blocks and internal buffering, in the form of a program that searches files for -text strings. - - ------------------------ --------------------------------- -------------------- - [Previous](01-05.html) [Table of Contents](index.html) [Next](02-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +text strings. \ No newline at end of file diff --git a/02-01.md b/02-01.md index 483e9d9..e3c3999 100644 --- a/02-01.md +++ b/02-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](01-06.html) [Table of Contents](index.html) [Next](02-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 2\ A World Apart {#Heading1} -------------- @@ -102,12 +98,4 @@ transformation that takes place between conception and implementation can reduce performance tremendously; for example, a programmer who implements a routine to search a list of 100,000 sorted items with a linear rather than binary search will end up with a disappointingly slow -program. - - ------------------------ --------------------------------- -------------------- - [Previous](01-06.html) [Table of Contents](index.html) [Next](02-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +program. \ No newline at end of file diff --git a/02-02.md b/02-02.md index ccce3f4..d9b1d50 100644 --- a/02-02.md +++ b/02-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](02-01.html) [Table of Contents](index.html) [Next](02-03.html) - ------------------------ --------------------------------- -------------------- - #### Transformation Inefficiencies {#Heading5} No matter how well an implementation is derived from the corresponding @@ -101,12 +97,4 @@ out such knowledge. ------------------- ------------------------------------------------------------------------------------------------------------------------------ ![](images/i.jpg) *Be forewarned, though: No matter how much you learn about programming the PC in assembly, there's always more to discover.* - ------------------- ------------------------------------------------------------------------------------------------------------------------------ - - ------------------------ --------------------------------- -------------------- - [Previous](02-01.html) [Table of Contents](index.html) [Next](02-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash + ------------------- ------------------------------------------------------------------------------------------------------------------------------ \ No newline at end of file diff --git a/02-03.md b/02-03.md index 0277af3..61fa243 100644 --- a/02-03.md +++ b/02-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](02-02.html) [Table of Contents](index.html) [Next](03-01.html) - ------------------------ --------------------------------- -------------------- - ### The Flexible Mind {#Heading8} Is the never-ending collection of information all there is to the @@ -110,12 +106,4 @@ With that in mind, what should the first step be? Development of the flexible mind is an obvious step. Still, the flexible mind is no better than the knowledge at its disposal. The first step in the journey toward mastering optimization at that exalted level, then, would seem to be -learning how to learn. - - ------------------------ --------------------------------- -------------------- - [Previous](02-02.html) [Table of Contents](index.html) [Next](03-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +learning how to learn. \ No newline at end of file diff --git a/03-01.md b/03-01.md index 314b0d4..5fc76d1 100644 --- a/03-01.md +++ b/03-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](02-03.html) [Table of Contents](index.html) [Next](03-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 3\ Assume Nothing {#Heading1} --------------- @@ -101,12 +97,4 @@ Listing 3.1 shows 8253-based timer software, consisting of three subroutines: **ZTimerOn, ZTimerOff**, and **ZTimerReport**. For the remainder of this book, I'll refer to these routines collectively as the "Zen timer." C-callable versions of the two precision Zen timers are -presented in Chapter K on the companion CD-ROM. - - ------------------------ --------------------------------- -------------------- - [Previous](02-03.html) [Table of Contents](index.html) [Next](03-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +presented in Chapter K on the companion CD-ROM. \ No newline at end of file diff --git a/03-02.md b/03-02.md index 6d9684c..c066f87 100644 --- a/03-02.md +++ b/03-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](03-01.html) [Table of Contents](index.html) [Next](03-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 3.1 PZTIMER.ASM** ; The precision Zen timer (PZTIMER.ASM) @@ -443,11 +439,3 @@ Code ends end - - ------------------------ --------------------------------- -------------------- - [Previous](03-01.html) [Table of Contents](index.html) [Next](03-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/03-03.md b/03-03.md index 691af5c..255e90f 100644 --- a/03-03.md +++ b/03-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](03-02.html) [Table of Contents](index.html) [Next](03-04.html) - ------------------------ --------------------------------- -------------------- - #### The Zen Timer Is a Means, Not an End {#Heading5} We're going to spend the rest of this chapter seeing what the Zen timer @@ -127,12 +123,4 @@ generate an interrupt; in fact, timer 2 can't do anything but drive the speaker. We need the interrupt generated by the output of timer 0 to tell us when the count has overflowed, and we will see shortly that the timer interrupt also makes it possible to time much longer periods than -the Zen timer shown in Listing 3.1 supports. - - ------------------------ --------------------------------- -------------------- - [Previous](03-02.html) [Table of Contents](index.html) [Next](03-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +the Zen timer shown in Listing 3.1 supports. \ No newline at end of file diff --git a/03-04.md b/03-04.md index a60d6e8..d3f3085 100644 --- a/03-04.md +++ b/03-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](03-03.html) [Table of Contents](index.html) [Next](03-05.html) - ------------------------ --------------------------------- -------------------- - In fact, the Zen timer shown in Listing 3.1 can only time intervals of up to about 54 ms in length, since that is the period of time that can be measured by timer 0 before its count turns over and repeats. @@ -145,12 +141,4 @@ David Miller for passing the idea on to me.) You may well want to devise still other approaches better suited to your needs than those I've presented. Go to it! I've just thrown out a few -possibilities to get you started. - - ------------------------ --------------------------------- -------------------- - [Previous](03-03.html) [Table of Contents](index.html) [Next](03-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +possibilities to get you started. \ No newline at end of file diff --git a/03-05.md b/03-05.md index cfb1622..05bc2e7 100644 --- a/03-05.md +++ b/03-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](03-04.html) [Table of Contents](index.html) [Next](03-06.html) - ------------------------ --------------------------------- -------------------- - ### Notes on the Zen Timer {#Heading10} The Zen timer subroutines are designed to be near-called from assembly @@ -160,12 +156,4 @@ execution time of start-up code in the timing interval. That's why the calls to **ZTimerOn** and **ZTimerOff** are in TESTCODE, not in PZTEST.ASM; this way, we have full control over which portion of TESTCODE is timed, and we can keep set-up code and the like out of the -timing interval. - - ------------------------ --------------------------------- -------------------- - [Previous](03-04.html) [Table of Contents](index.html) [Next](03-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +timing interval. \ No newline at end of file diff --git a/03-06.md b/03-06.md index 4464719..84f71ea 100644 --- a/03-06.md +++ b/03-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](03-05.html) [Table of Contents](index.html) [Next](03-07.html) - ------------------------ --------------------------------- -------------------- - Listing 3.3 is used by naming it TESTCODE, assembling both Listing 3.2 (which includes TESTCODE) and Listing 3.1 with TASM or MASM, and linking the two resulting OBJ files together by way of the Borland orMicrosoft @@ -156,12 +152,4 @@ You should not use the long-period Zen timer to time code that requires interrupts to be disabled for more than 54 ms at a stretch during the timing interval, since when interrupts are disabled the long-period Zen timer is subject to the same 54 ms maximum measurement time as the -precision Zen timer. - - ------------------------ --------------------------------- -------------------- - [Previous](03-05.html) [Table of Contents](index.html) [Next](03-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +precision Zen timer. \ No newline at end of file diff --git a/03-07.md b/03-07.md index 576b336..b8c05e0 100644 --- a/03-07.md +++ b/03-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](03-06.html) [Table of Contents](index.html) [Next](03-08.html) - ------------------------ --------------------------------- -------------------- - While permitting the timer interrupt to occur allows long intervals to be timed, that same interrupt makes the long-period Zen timer less accurate than the precision Zen timer, since the time the BIOS spends @@ -704,11 +700,3 @@ computers. Code ends end - - ------------------------ --------------------------------- -------------------- - [Previous](03-06.html) [Table of Contents](index.html) [Next](03-08.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/03-08.md b/03-08.md index e693863..c1c6dfd 100644 --- a/03-08.md +++ b/03-08.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](03-07.html) [Table of Contents](index.html) [Next](03-09.html) - ------------------------ --------------------------------- -------------------- - Moreover, because it uses an undocumented feature, the timer-stop approach could conceivably cause erratic 8253 operation, which could in turn seriously affect your computer's operation until the next reboot. @@ -128,12 +124,4 @@ linking the two files together by way of the Microsoft or Borland linker. Listing 3.7 shows a batch file, named LZTIME.BAT, which does all of the above, generating and running the executable file LZTEST.EXE. LZTIME.BAT assumes that the file LZTIMER.ASM contains Listing 3.5 and -the file LZTEST.ASM contains Listing 3.6. - - ------------------------ --------------------------------- -------------------- - [Previous](03-07.html) [Table of Contents](index.html) [Next](03-09.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +the file LZTEST.ASM contains Listing 3.6. \ No newline at end of file diff --git a/03-09.md b/03-09.md index 41e5d8e..d625905 100644 --- a/03-09.md +++ b/03-09.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](03-08.html) [Table of Contents](index.html) [Next](03-10.html) - ------------------------ --------------------------------- -------------------- - **LISTING 3.7 LZTIME.BAT** echo off @@ -140,11 +136,3 @@ code to use C-style external label names and the small model C code segment. (In C++, use the "C" specifier, as in extern "C" ZTimerOn(void); - - ------------------------ --------------------------------- -------------------- - [Previous](03-08.html) [Table of Contents](index.html) [Next](03-10.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/03-10.md b/03-10.md index 8c66c56..d8e9239 100644 --- a/03-10.md +++ b/03-10.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](03-09.html) [Table of Contents](index.html) [Next](04-01.html) - ------------------------ --------------------------------- -------------------- - when declaring the timer routines **extern**, so that name-mangling doesn't occur, and the linker can find the routines' C-style names.) @@ -124,12 +120,4 @@ periods. Imperfections notwithstanding, the Zen timer is a good tool for exploring C code and x86 family assembly language, and it's a tool we'll -use frequently for the remainder of this book. - - ------------------------ --------------------------------- -------------------- - [Previous](03-09.html) [Table of Contents](index.html) [Next](04-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +use frequently for the remainder of this book. \ No newline at end of file diff --git a/04-01.md b/04-01.md index 5aadf6f..c89dd5d 100644 --- a/04-01.md +++ b/04-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](03-10.html) [Table of Contents](index.html) [Next](04-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 4\ In the Lair of the Cycle-Eaters {#Heading1} -------------------------------- @@ -150,12 +146,4 @@ only 8 bits wide, as shown in Figure 4.2. The result of this mismatch is simple: Word-sized data can be transferred between the 8088 and memory or peripherals at only one-half the maximum rate of the 8086, which is to say one-half the maximum rate for which the Execution Unit of the -8088 was designed. - - ------------------------ --------------------------------- -------------------- - [Previous](03-10.html) [Table of Contents](index.html) [Next](04-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +8088 was designed. \ No newline at end of file diff --git a/04-02.md b/04-02.md index 2391d24..c9e7f71 100644 --- a/04-02.md +++ b/04-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](04-01.html) [Table of Contents](index.html) [Next](04-03.html) - ------------------------ --------------------------------- -------------------- - ![](images/04-01.jpg)\ **Figure 4.1**  *The location of the major cycle-eaters in the IBM PC.* @@ -154,12 +150,4 @@ relevant to real programming problems. On the other hand, optimal code is an elusive thing indeed; by no means should you assume that the code in this book is ideal! Examine it, question it, and improve upon it, for an inquisitive, skeptical mind is an important part of the Zen of -assembly optimization. - - ------------------------ --------------------------------- -------------------- - [Previous](04-01.html) [Table of Contents](index.html) [Next](04-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +assembly optimization. \ No newline at end of file diff --git a/04-03.md b/04-03.md index 9d40088..ce481d7 100644 --- a/04-03.md +++ b/04-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](04-02.html) [Table of Contents](index.html) [Next](04-04.html) - ------------------------ --------------------------------- -------------------- - Back to the 8-bit bus cycle-eater. As I've said, in 8088 work you should strive to use byte-sized memory variables whenever possible. That does *not* mean that you should use 2 byte-sized memory accesses to @@ -157,12 +153,4 @@ how long it will take that instruction to reach the prefetch queue if it's not there already. Thanks to the low performance of the 8088's external data bus, that's a glaring omission—but, alas, an unavoidable one. Let's look at why the official execution times are wrong, and why -that can't be helped. - - ------------------------ --------------------------------- -------------------- - [Previous](04-02.html) [Table of Contents](index.html) [Next](04-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +that can't be helped. \ No newline at end of file diff --git a/04-04.md b/04-04.md index c775fff..bafb029 100644 --- a/04-04.md +++ b/04-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](04-03.html) [Table of Contents](index.html) [Next](04-05.html) - ------------------------ --------------------------------- -------------------- - #### Official Execution Times Are Only Part of the Story {#Heading10} The sequence of 5 **SHR** instructions in the last example is 10 bytes @@ -147,12 +143,4 @@ instructions which have sucked the prefetch queue dry, so overall performance reflects instruction fetch time. By contrast, each **SHR** in Listing 4.6 follows a **MUL** instruction which leaves the prefetch queue full, so overall performance reflects Execution Unit execution -time. - - ------------------------ --------------------------------- -------------------- - [Previous](04-03.html) [Table of Contents](index.html) [Next](04-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +time. \ No newline at end of file diff --git a/04-05.md b/04-05.md index d4aa19e..7e5c0db 100644 --- a/04-05.md +++ b/04-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](04-04.html) [Table of Contents](index.html) [Next](04-06.html) - ------------------------ --------------------------------- -------------------- - Clearly, either instruction fetch time *or* Execution Unit execution time—or even a mix of the two, if an instruction is partially prefetched—can determine code performance. Some people operate under a @@ -145,12 +141,4 @@ bytes long, thanks to the prefetch queue bottleneck. Short instructions are nonetheless generally faster than long instructions, thanks to the combination of fewer instruction bytes and faster Execution Unit execution times, and should be used as much as possible—just don't -expect them to run at their "official" documented speeds. - - ------------------------ --------------------------------- -------------------- - [Previous](04-04.html) [Table of Contents](index.html) [Next](04-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +expect them to run at their "official" documented speeds. \ No newline at end of file diff --git a/04-06.md b/04-06.md index 3cd8733..9330ed9 100644 --- a/04-06.md +++ b/04-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](04-05.html) [Table of Contents](index.html) [Next](04-07.html) - ------------------------ --------------------------------- -------------------- - More than anything, the above rules mean using the registers as heavily as possible, both because register-only instructions are short and because they don't perform memory accesses to read or write operands. @@ -128,12 +124,4 @@ occupies cycles during which the 8088 would otherwise be accessing memory. ![](images/04-05.jpg)\ - **Figure 4.5**  *The PC bus dynamic RAM (DRAM) refresh.* - - ------------------------ --------------------------------- -------------------- - [Previous](04-05.html) [Table of Contents](index.html) [Next](04-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash + **Figure 4.5**  *The PC bus dynamic RAM (DRAM) refresh.* \ No newline at end of file diff --git a/04-07.md b/04-07.md index 24465f4..7c42d95 100644 --- a/04-07.md +++ b/04-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](04-06.html) [Table of Contents](index.html) [Next](04-08.html) - ------------------------ --------------------------------- -------------------- - #### The Impact of DRAM Refresh {#Heading17} Let's look at examples from opposite ends of the spectrum in terms of @@ -143,12 +139,4 @@ Wait states are cycles during which a bus access by the CPU to a device on the PC's bus is temporarily halted by that device while the device gets ready to complete the read or write. Wait states are well and truly the lowest level of code performance. Everything we have discussed (and -will discuss)—even DMA accesses—can be affected by wait states. - - ------------------------ --------------------------------- -------------------- - [Previous](04-06.html) [Table of Contents](index.html) [Next](04-08.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +will discuss)—even DMA accesses—can be affected by wait states. \ No newline at end of file diff --git a/04-08.md b/04-08.md index 51c48c6..1516a70 100644 --- a/04-08.md +++ b/04-08.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](04-07.html) [Table of Contents](index.html) [Next](04-09.html) - ------------------------ --------------------------------- -------------------- - Wait states exist because the CPU must to be able to coexist with any adapter, no matter how slow (within reason). The 8088 expects to be able to complete each bus access—a memory or I/O read or write—in 4 cycles, @@ -134,12 +130,4 @@ the 8088's already-poor memory access performance in half. Running your code from display memory is sort of like running on a hypothetical 8084—an 8086 with a *4-bit* bus. Not recommended!) Given that your code and data reside in normal system memory below the 640K mark, how great -an impact does the display adapter cycle-eater have on performance? - - ------------------------ --------------------------------- -------------------- - [Previous](04-07.html) [Table of Contents](index.html) [Next](04-09.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +an impact does the display adapter cycle-eater have on performance? \ No newline at end of file diff --git a/04-09.md b/04-09.md index f209d66..980dd88 100644 --- a/04-09.md +++ b/04-09.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](04-08.html) [Table of Contents](index.html) [Next](04-10.html) - ------------------------ --------------------------------- -------------------- - The answer varies considerably depending on what display adapter and what display mode we're talking about. The display adapter cycle-eater is worst with the Enhanced Graphics Adapter (EGA) and the original Video @@ -138,12 +134,4 @@ cycle-eater can *more than double* the execution time of 8088 code! Bear in mind that we're talking about a worst case here; the impact of the display adapter cycle-eater is proportional to the percent of time a -given code sequence spends accessing display memory. - - ------------------------ --------------------------------- -------------------- - [Previous](04-08.html) [Table of Contents](index.html) [Next](04-10.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +given code sequence spends accessing display memory. \ No newline at end of file diff --git a/04-10.md b/04-10.md index 83778b3..7eb35ef 100644 --- a/04-10.md +++ b/04-10.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](04-09.html) [Table of Contents](index.html) [Next](05-01.html) - ------------------------ --------------------------------- -------------------- - ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ![](images/i.jpg) *A line-drawing subroutine, which executes perhaps a dozen instructions for each display memory access, generally loses less performance to the display adapter cycle-eater than does a block-copy or scrolling subroutine that uses **REP MOVS** instructions. Scaled and three-dimensional graphics, which spend a great deal of time performing calculations (often using very slow floating-point arithmetic), tend to suffer less.* ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ @@ -118,12 +114,4 @@ cycle-eaters vary in importance on later x86-family processors, with some cycle-eaters vanishing altogether and new ones appearing, the concept that understanding these obscure gremlins is a key to performance remains unchanged, as we'll see again and again in later -chapters. - - ------------------------ --------------------------------- -------------------- - [Previous](04-09.html) [Table of Contents](index.html) [Next](05-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +chapters. \ No newline at end of file diff --git a/05-01.md b/05-01.md index 1709eb5..c688d13 100644 --- a/05-01.md +++ b/05-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](04-10.html) [Table of Contents](index.html) [Next](05-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 5\ Crossing the Border {#Heading1} -------------------- @@ -112,12 +108,4 @@ for the first occurrence of a second string. However, while **strstr()** would work, it isn't ideal for our purposes. The problem is this: Where we want to search a fixed-length buffer for the first occurrence of a string, **strstr()** searches a *string* for the first occurrence of -another string. - - ------------------------ --------------------------------- -------------------- - [Previous](04-10.html) [Table of Contents](index.html) [Next](05-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +another string. \ No newline at end of file diff --git a/05-02.md b/05-02.md index 2d09a46..32cb5ab 100644 --- a/05-02.md +++ b/05-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](05-01.html) [Table of Contents](index.html) [Next](05-03.html) - ------------------------ --------------------------------- -------------------- - We could put a zero byte at the end of our buffer to allow **strstr()** to work, but why bother? The **strstr()** function must spend time either checking for the end of the string being searched or determining @@ -115,12 +111,4 @@ Listing 5.1 nicely illustrates the core concept of restartable blocks: Organize your program so that you can do your processing within each block as fast as you could if there were only one block—which is to say at top speed—and make your blocks as large as possible in order to -minimize the overhead associated with going from one block to the next. - - ------------------------ --------------------------------- -------------------- - [Previous](05-01.html) [Table of Contents](index.html) [Next](05-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +minimize the overhead associated with going from one block to the next. \ No newline at end of file diff --git a/05-03.md b/05-03.md index c39bd1d..3c82564 100644 --- a/05-03.md +++ b/05-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](05-02.html) [Table of Contents](index.html) [Next](05-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 5.1 SEARCH.C** /* Program to search the file specified by the first command-line @@ -169,11 +165,3 @@ exit(Found); /* Return the found/not found status as the DOS errorlevel */ } - - ------------------------ --------------------------------- -------------------- - [Previous](05-02.html) [Table of Contents](index.html) [Next](05-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/05-04.md b/05-04.md index 10c691f..61eb852 100644 --- a/05-04.md +++ b/05-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](05-03.html) [Table of Contents](index.html) [Next](05-05.html) - ------------------------ --------------------------------- -------------------- - ### Interpreting Where the Cycles Go {#Heading8} To boost the overall performance of Listing 5.1, I would normally @@ -76,12 +72,4 @@ Likewise, assembly can switch back to **REPNZ SCASB** after a non-match much more quickly than Listing 5.1. The switching overhead is high; when searching a file completely filled with the character z for the string "zy," Listing 5.1 takes almost 1/2 minute, or nearly an order of -magnitude longer than when searching a file filled with normal text. - - ------------------------ --------------------------------- -------------------- - [Previous](05-03.html) [Table of Contents](index.html) [Next](05-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +magnitude longer than when searching a file filled with normal text. \ No newline at end of file diff --git a/05-05.md b/05-05.md index 6a3350c..43d188c 100644 --- a/05-05.md +++ b/05-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](05-04.html) [Table of Contents](index.html) [Next](06-01.html) - ------------------------ --------------------------------- -------------------- - It might also be worth converting the search engine to assembly for searches performed entirely in memory; with the overhead of file access eliminated, improvements in search-engine performance would translate @@ -67,12 +63,4 @@ itself with greatly improved performance. And when speed is *not* an issue, of course, or in code that's not time-critical, you wouldn't dream of wasting your time on optimization. -Would you? - - ------------------------ --------------------------------- -------------------- - [Previous](05-04.html) [Table of Contents](index.html) [Next](06-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +Would you? \ No newline at end of file diff --git a/06-01.md b/06-01.md index c784e97..7ae487b 100644 --- a/06-01.md +++ b/06-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](05-05.html) [Table of Contents](index.html) [Next](06-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 6\ Looking Past Face Value {#Heading1} ------------------------ @@ -120,11 +116,3 @@ Or you could let the processor do the arithmetic for you in a single instruction: mov al,[bx+si] - - ------------------------ --------------------------------- -------------------- - [Previous](05-05.html) [Table of Contents](index.html) [Next](06-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/06-02.md b/06-02.md index ff23afc..4698551 100644 --- a/06-02.md +++ b/06-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](06-01.html) [Table of Contents](index.html) [Next](07-01.html) - ------------------------ --------------------------------- -------------------- - The two approaches are functionally interchangeable but *not* equivalent from a performance standpoint, and which is better depends on the particular context. If it's a one-shot memory access, it's best to let @@ -173,12 +169,4 @@ cycles is a pretty neat trick, even though it works only on a 386 or I'd like to extend my thanks to Duane Strong of Metagraphics for his help in brainstorming uses for the 386 version of **LEA** and for -pointing out the complications of 486 instruction timings. - - ------------------------ --------------------------------- -------------------- - [Previous](06-01.html) [Table of Contents](index.html) [Next](07-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +pointing out the complications of 486 instruction timings. \ No newline at end of file diff --git a/07-01.md b/07-01.md index fecdfa6..fe9cb76 100644 --- a/07-01.md +++ b/07-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](06-02.html) [Table of Contents](index.html) [Next](07-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 7\ Local Optimization {#Heading1} ------------------- @@ -111,12 +107,4 @@ the relative performances of **LOOP** and **DEC CX/JNZ** on a cached ------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ![](images/i.jpg) *Things are stranger still for **LOOP**'s relative **JCXZ,** which branches if and only if CX is zero. **JCXZ** is faster than **AND CX,CX/JZ** on the 8088 and 80286, and equivalent on the 80386—but is about twice as slow on the 486!* - ------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - ------------------------ --------------------------------- -------------------- - [Previous](06-02.html) [Table of Contents](index.html) [Next](07-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash + ------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/07-02.md b/07-02.md index e2736cc..8fc57a6 100644 --- a/07-02.md +++ b/07-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](07-01.html) [Table of Contents](index.html) [Next](07-03.html) - ------------------------ --------------------------------- -------------------- - By the way, don't fall victim to the lures of **JCXZ** and do something like this: @@ -99,12 +95,4 @@ most that counting cycles could buy us in this case. (All right, already; **LOOPNZ** could be used at the bottom of the loop, and other optimizations are surely possible, but all that won't add up to anywhere near the benefits we're about to see from local optimization, and that's -the whole point.) - - ------------------------ --------------------------------- -------------------- - [Previous](07-01.html) [Table of Contents](index.html) [Next](07-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +the whole point.) \ No newline at end of file diff --git a/07-03.md b/07-03.md index f385064..1e0ee93 100644 --- a/07-03.md +++ b/07-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](07-02.html) [Table of Contents](index.html) [Next](07-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 7.1 L7-1.ASM** ; Program to illustrate searching through a buffer of a specified @@ -104,12 +100,4 @@ that three-quarters of the **LOOP**s are eliminated. Listings 7.1 and 7.2 perform exactly the same task, and they use the same instructions in the loop—the searching algorithm hasn't changed in any way—but we have sequenced the instructions differently in Listing 7.2, and that makes -all the difference. - - ------------------------ --------------------------------- -------------------- - [Previous](07-02.html) [Table of Contents](index.html) [Next](07-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +all the difference. \ No newline at end of file diff --git a/07-04.md b/07-04.md index b10827e..90c9ad5 100644 --- a/07-04.md +++ b/07-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](07-03.html) [Table of Contents](index.html) [Next](07-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 7.2 L7-2.ASM** ; Program to illustrate searching through a buffer of a specified @@ -145,12 +141,4 @@ avenues. ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ![](images/i.jpg) *The point is simply this: You can gain far more by stepping back a bit and thinking of the fastest overall way for the CPU to perform a task than you can by saving a cycle here or there using different instructions. Try to think at the level of sequences of instructions rather than individual instructions, and learn to treat x86 instructions as building blocks with unique characteristics rather than as instructions dedicated to specific tasks.* - ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - ------------------------ --------------------------------- -------------------- - [Previous](07-03.html) [Table of Contents](index.html) [Next](07-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash + ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/07-05.md b/07-05.md index 6a17efc..725e0b7 100644 --- a/07-05.md +++ b/07-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](07-04.html) [Table of Contents](index.html) [Next](08-01.html) - ------------------------ --------------------------------- -------------------- - #### Rotating and Shifting with Tables {#Heading8} As another example of local optimization, consider the matter of @@ -175,12 +171,4 @@ the following: ADD AX,1 ADC DX,0 -As always, pay attention! - - ------------------------ --------------------------------- -------------------- - [Previous](07-04.html) [Table of Contents](index.html) [Next](08-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +As always, pay attention! \ No newline at end of file diff --git a/08-01.md b/08-01.md index 9004f52..0b7edeb 100644 --- a/08-01.md +++ b/08-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](07-05.html) [Table of Contents](index.html) [Next](08-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 8\ Speeding Up C with Assembly Language {#Heading1} ------------------------------------- @@ -114,12 +110,4 @@ your assembly code. True, in assembly you can pass parameters in registers, but the calls and returns themselves are still slow; if the extra cycles they take don't affect performance, then the code they're in probably isn't critical, and perhaps you've chosen to convert too -much code to assembly, eh? - - ------------------------ --------------------------------- -------------------- - [Previous](07-05.html) [Table of Contents](index.html) [Next](08-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +much code to assembly, eh? \ No newline at end of file diff --git a/08-02.md b/08-02.md index dabb075..c2eddcb 100644 --- a/08-02.md +++ b/08-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](08-01.html) [Table of Contents](index.html) [Next](08-03.html) - ------------------------ --------------------------------- -------------------- - ### Stack Frames Slow So Much {#Heading5} C compilers work within the stack frame model, whereby variables reside @@ -130,12 +126,4 @@ Listing 8.1 is the sample C application I'm going to use to examine optimization in action. Listing 8.1 isn't really complete—it doesn't handle the "no-matches" case well, and it assumes that the sum of all matches will fit into an **int—**but it will do just fine as an -optimization example. - - ------------------------ --------------------------------- -------------------- - [Previous](08-01.html) [Table of Contents](index.html) [Next](08-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +optimization example. \ No newline at end of file diff --git a/08-03.md b/08-03.md index 4da111f..ae1e1d9 100644 --- a/08-03.md +++ b/08-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](08-02.html) [Table of Contents](index.html) [Next](08-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 8.1 L8-1.C** /* Program to search an array spanning a linked list of variable- @@ -176,11 +172,3 @@ instruction can be used. mov WORD PTR [bp-2],di ;IDMatchSum mov WORD PTR [bp-4],dx ;IDMatchCount $FB264: - - ------------------------ --------------------------------- -------------------- - [Previous](08-02.html) [Table of Contents](index.html) [Next](08-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/08-04.md b/08-04.md index be2e277..e11ffd3 100644 --- a/08-04.md +++ b/08-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](08-03.html) [Table of Contents](index.html) [Next](08-05.html) - ------------------------ --------------------------------- -------------------- - It's hard to squeeze much more performance from this code by tweaking it, as exemplified by Listing 8.3, a fine-tuned assembly version of **FindIDAverage** that was produced by looking at the assembly output of @@ -219,11 +215,3 @@ but not a tremendous return for the optimization effort invested. ret _FindIDAverage ENDP end - - ------------------------ --------------------------------- -------------------- - [Previous](08-03.html) [Table of Contents](index.html) [Next](08-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/08-05.md b/08-05.md index e7b42f3..70f0592 100644 --- a/08-05.md +++ b/08-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](08-04.html) [Table of Contents](index.html) [Next](09-01.html) - ------------------------ --------------------------------- -------------------- - Listings 8.5 and 8.6 together go the final step and change the rules in favor of assembly language. Listing 8.5 creates the same list of linked blocks as Listing 8.1. However, instead of storing an array of @@ -173,12 +169,4 @@ the low end, resulting in critical code that runs just about as fast as the hardware permits. The only software that can do that is located north of your sternum and slightly aft of your nose. Dust it off and put it to work—and your code will never again be confused with anything by -Hamilton, Joe, Frank, eynolds or Bo Donaldson and the Heywoods. - - ------------------------ --------------------------------- -------------------- - [Previous](08-04.html) [Table of Contents](index.html) [Next](09-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +Hamilton, Joe, Frank, eynolds or Bo Donaldson and the Heywoods. \ No newline at end of file diff --git a/09-01.md b/09-01.md index 771fbdc..761a0c7 100644 --- a/09-01.md +++ b/09-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](08-05.html) [Table of Contents](index.html) [Next](09-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 9\ Hints My Readers Gave Me {#Heading1} ------------------------- @@ -171,11 +167,3 @@ above is faster than this: JNC CopyDone ;done if even copy length MOVSB ;copy the odd byte CopyDone: - - ------------------------ --------------------------------- -------------------- - [Previous](08-05.html) [Table of Contents](index.html) [Next](09-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/09-02.md b/09-02.md index fe6b02a..5926fe4 100644 --- a/09-02.md +++ b/09-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](09-01.html) [Table of Contents](index.html) [Next](09-03.html) - ------------------------ --------------------------------- -------------------- - However, it generally is. Sure, if the length is odd, John's approach incurs a penalty approximately equal to the **REP** startup time for **MOVSB**. However, if the length is even, John's approach doesn't @@ -130,12 +126,4 @@ my approach, you'd use **REPNZ SCASB** to scan for each occurrence of would make more sense to scan for "Q," then back up one character and check the whole string when a "Q" is found, as shown in Figure 9.2. "Q" is likely to occur much less often, resulting in many fewer whole-string -checks and much faster processing. - - ------------------------ --------------------------------- -------------------- - [Previous](09-01.html) [Table of Contents](index.html) [Next](09-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +checks and much faster processing. \ No newline at end of file diff --git a/09-03.md b/09-03.md index 8c4a177..8da9504 100644 --- a/09-03.md +++ b/09-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](09-02.html) [Table of Contents](index.html) [Next](09-04.html) - ------------------------ --------------------------------- -------------------- - Listing 9.1 implements the scan-on-first-character approach. Listing 9.2 scans for whatever character the caller specifies. Listing 9.3 is a test program used to compare the two approaches. How much difference does @@ -123,11 +119,3 @@ using **REPZ CMPS** to check scanning matches. ret _FindStringendp end - - ------------------------ --------------------------------- -------------------- - [Previous](09-02.html) [Table of Contents](index.html) [Next](09-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/09-04.md b/09-04.md index bf20016..28d6c23 100644 --- a/09-04.md +++ b/09-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](09-03.html) [Table of Contents](index.html) [Next](09-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 9.2 L9-2.ASM** ; Searches a text buffer for a text string. Uses REPNZ SCASB to scan @@ -135,11 +131,3 @@ strncpy(TempBuffer, MatchPtr, DISPLAY_LENGTH)); } } - - ------------------------ --------------------------------- -------------------- - [Previous](09-03.html) [Table of Contents](index.html) [Next](09-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/09-05.md b/09-05.md index 067a211..0d263e4 100644 --- a/09-05.md +++ b/09-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](09-04.html) [Table of Contents](index.html) [Next](09-06.html) - ------------------------ --------------------------------- -------------------- - You'll notice that in Listing 9.2 I didn't use a table of character frequencies in English text to determine the character for which to scan, but rather let the caller make that choice. Each buffer of bytes @@ -111,12 +107,4 @@ divisor, dividing the absolute value of the dividend by the absolute value of the divisor, and applying the stored signs to set the proper signs for the quotient and remainder. There may be more clever ways to produce the same result, by using **IDIV**, for example; if you know of -one, drop me a line c/o Coriolis Group Books. - - ------------------------ --------------------------------- -------------------- - [Previous](09-04.html) [Table of Contents](index.html) [Next](09-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +one, drop me a line c/o Coriolis Group Books. \ No newline at end of file diff --git a/09-06.md b/09-06.md index a77eb3c..23fbb6c 100644 --- a/09-06.md +++ b/09-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](09-05.html) [Table of Contents](index.html) [Next](09-07.html) - ------------------------ --------------------------------- -------------------- - **LISTING 9.5 L9-5.ASM** ; Divides an arbitrarily long unsigned dividend by a 16-bit unsigned @@ -130,12 +126,4 @@ appropriately to produce the desired effect. It can be done: I did it in Turbo C some years back, and trimmed the size of a program (admittedly, a large one) by several K—not bad, when you consider that the "sweet spot" optimization is essentially free, with no code reorganization, -change in logic, or heavy thinking involved. - - ------------------------ --------------------------------- -------------------- - [Previous](09-05.html) [Table of Contents](index.html) [Next](09-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +change in logic, or heavy thinking involved. \ No newline at end of file diff --git a/09-07.md b/09-07.md index 6175963..b25637c 100644 --- a/09-07.md +++ b/09-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](09-06.html) [Table of Contents](index.html) [Next](10-01.html) - ------------------------ --------------------------------- -------------------- - #### Hard-Core Cycle Counting {#Heading10} Next, we come to an item that cycle counters will love, especially since @@ -140,12 +136,4 @@ Be warned, though, that I've found **OR, AND, ADD**, and the like to be a cycle slower than **MOV** when working with immediate operands on the 386 under some circumstances, for reasons that thus far escape me. This just reinforces the first rule of optimization: Measure your code in -action, and place not your trust in documented cycle times. - - ------------------------ --------------------------------- -------------------- - [Previous](09-06.html) [Table of Contents](index.html) [Next](10-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +action, and place not your trust in documented cycle times. \ No newline at end of file diff --git a/10-01.md b/10-01.md index 2c8122b..42363ec 100644 --- a/10-01.md +++ b/10-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](09-07.html) [Table of Contents](index.html) [Next](10-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 10\ Patient Coding, Faster Code {#Heading1} ---------------------------- @@ -126,12 +122,4 @@ Eratosthenes (we'd have been in big trouble if the ancient Greeks had had computers), mainly because after about five minutes of brute force-type work, people's attention gets diverted to other important matters, such as how far a paper airplane will fly from a second-story -window. - - ------------------------ --------------------------------- -------------------- - [Previous](09-07.html) [Table of Contents](index.html) [Next](10-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +window. \ No newline at end of file diff --git a/10-02.md b/10-02.md index ec0c35b..b34879c 100644 --- a/10-02.md +++ b/10-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](10-01.html) [Table of Contents](index.html) [Next](10-03.html) - ------------------------ --------------------------------- -------------------- - Not so nowadays, though. Computers love boring work; they're very patient and disciplined, and, besides, one human year = seven dog years = two zillion computer years. So when we're faced with a problem that @@ -239,11 +235,3 @@ in Listing 10.2. /* Now recursively call this function to continue the process */ return(gcd(int1, int2)); } - - ------------------------ --------------------------------- -------------------- - [Previous](10-01.html) [Table of Contents](index.html) [Next](10-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/10-03.md b/10-03.md index 518631a..bb4265f 100644 --- a/10-03.md +++ b/10-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](10-02.html) [Table of Contents](index.html) [Next](10-04.html) - ------------------------ --------------------------------- -------------------- - Listing 10.2 repeatedly subtracts iS from iL until iL becomes less than or equal to iS. If iL becomes equal to iS, then that's the GCD; alternatively, if iL becomes *less* than iS, iL and iS switch values, @@ -160,12 +156,4 @@ Microsoft C/C++'s maximum optimization, and also shows the performance of Listing 10.5, an assembly language version of Listing 10.4. Sure, the optimized versions are faster than the unoptimized version of Listing 10.4—but the gains are small compared to those realized from the -higher-level optimizations in Listings 10.2 through 10.4. - - ------------------------ --------------------------------- -------------------- - [Previous](10-02.html) [Table of Contents](index.html) [Next](10-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +higher-level optimizations in Listings 10.2 through 10.4. \ No newline at end of file diff --git a/10-04.md b/10-04.md index a47fd91..624b0b3 100644 --- a/10-04.md +++ b/10-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](10-03.html) [Table of Contents](index.html) [Next](11-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 10.5 L10-5.ASM** ; Finds and returns the greatest common divisor of two integers. @@ -129,12 +125,4 @@ breakthroughs. Stop, look, listen—and think. Not only will you find that it's a more productive and creative way to program—but you'll also find that it's more fun. -And think what you could do with all those extra computer years! - - ------------------------ --------------------------------- -------------------- - [Previous](10-03.html) [Table of Contents](index.html) [Next](11-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +And think what you could do with all those extra computer years! \ No newline at end of file diff --git a/11-01.md b/11-01.md index 1709d79..ef1c8c4 100644 --- a/11-01.md +++ b/11-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](10-04.html) [Table of Contents](index.html) [Next](11-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 11\ Pushing the 286 and 386 {#Heading1} ------------------------ @@ -142,12 +138,4 @@ to use byte-sized memory variables in preference to word-sized variables, at least so long as word-sized variables start at even addresses, as we'll see shortly. On the other hand, access to byte-sized variables still isn't any *slower* than access to word-sized variables, -so you can use whichever size suits a given task best. - - ------------------------ --------------------------------- -------------------- - [Previous](10-04.html) [Table of Contents](index.html) [Next](11-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +so you can use whichever size suits a given task best. \ No newline at end of file diff --git a/11-02.md b/11-02.md index 5c48ac2..ab7015a 100644 --- a/11-02.md +++ b/11-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](11-01.html) [Table of Contents](index.html) [Next](11-03.html) - ------------------------ --------------------------------- -------------------- - You might think that the elimination of the 8-bit bus cycle-eater would mean that the prefetch queue cycle-eater would also vanish, since on the 8088 the prefetch queue cycle-eater is a side effect of the 8-bit bus. @@ -142,12 +138,4 @@ perspective, the 286 in an AT has two-thirds of a 16-bit bus (a 10.7-bit bus?), since every bus access on an AT takes 50 percent longer than it should. A 286 running at 10 MHz *should* be able to access memory at a maximum rate of 1 word every 200 ns; in a 10 MHz AT, however, that rate -is reduced to 1 word every 300 ns by the one-wait-state memory. - - ------------------------ --------------------------------- -------------------- - [Previous](11-01.html) [Table of Contents](index.html) [Next](11-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +is reduced to 1 word every 300 ns by the one-wait-state memory. \ No newline at end of file diff --git a/11-03.md b/11-03.md index 06d23ed..34fde18 100644 --- a/11-03.md +++ b/11-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](11-02.html) [Table of Contents](index.html) [Next](11-04.html) - ------------------------ --------------------------------- -------------------- - In short, a close relative of our old friend the 8-bit bus cycle-eater—the system memory wait state cycle-eater—haunts us still on all but zero-wait-state 286 and 386 computers, and that means that the @@ -165,12 +161,4 @@ target instruction for any branch effectively cuts the instruction-fetching power of the 286 in half for the first instruction fetch after that branch. While that may not sound like much, you'd be surprised at what it can do to tight loops; in fact, a brief story is in -order. - - ------------------------ --------------------------------- -------------------- - [Previous](11-02.html) [Table of Contents](index.html) [Next](11-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +order. \ No newline at end of file diff --git a/11-04.md b/11-04.md index 7a7b266..9edeae8 100644 --- a/11-04.md +++ b/11-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](11-03.html) [Table of Contents](index.html) [Next](11-05.html) - ------------------------ --------------------------------- -------------------- - When I was developing the Zen timer, I used my trusty 10 MHz 286-based AT clone to verify the basic functionality of the timer by measuring the performance of simple instruction sequences. I was cruising along with @@ -158,12 +154,4 @@ display adapter such as a standard VGA is reasonably well-matched to an 8088's memory access speed. Granted, access to a VGA slows the 8088 down considerably—but, as we're about to find out, "considerably" is a relative term. What a VGA does to PC performance is nothing compared to -what it does to faster computers. - - ------------------------ --------------------------------- -------------------- - [Previous](11-03.html) [Table of Contents](index.html) [Next](11-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +what it does to faster computers. \ No newline at end of file diff --git a/11-05.md b/11-05.md index b1b302a..9785862 100644 --- a/11-05.md +++ b/11-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](11-04.html) [Table of Contents](index.html) [Next](11-06.html) - ------------------------ --------------------------------- -------------------- - Under ideal conditions, a 286 can access memory much, much faster than an 8088. A 10 MHz 286 is capable of accessing a word of system memory every 0.20 ms with **REP MOVSW**, dwarfing the 1 byte every 1.31 µs that @@ -133,12 +129,4 @@ of simple instructions on the 486 and especially on the Pentium.) What's more, both old and new instructions support 32-bit operations on the 386. For example, it's relatively simple to copy data in chunks of 4 bytes on a 386, even in real mode, by using the **MOVSD** ("move string -double") instruction, or to negate a 32-bit value with **NEG eax**. - - ------------------------ --------------------------------- -------------------- - [Previous](11-04.html) [Table of Contents](index.html) [Next](11-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +double") instruction, or to negate a 32-bit value with **NEG eax**. \ No newline at end of file diff --git a/11-06.md b/11-06.md index 90064e1..e7aa966 100644 --- a/11-06.md +++ b/11-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](11-05.html) [Table of Contents](index.html) [Next](11-07.html) - ------------------------ --------------------------------- -------------------- - Finally, it's possible in real mode to use the 386's new addressing modes, in which *any* 32-bit general-purpose register or pair of registers can be used to address memory. What's more, multiplication of @@ -116,11 +112,3 @@ Theory confirmed. add dx,100h endm call ZTimerOff - - ------------------------ --------------------------------- -------------------- - [Previous](11-05.html) [Table of Contents](index.html) [Next](11-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/11-07.md b/11-07.md index 93d8776..61bfc47 100644 --- a/11-07.md +++ b/11-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](11-06.html) [Table of Contents](index.html) [Next](11-08.html) - ------------------------ --------------------------------- -------------------- - **LISTING 11.5 L11-5.ASM** ; @@ -100,12 +96,4 @@ purpose, and didn't intentionally provide any alternative approach, so we'll have to devise an alternative approach of our own. To do that, we'll have to search for instructions that contain some of the same functionality as **POPF**, in the hope that one of those instructions -can be used in some way to replace **POPF**. - - ------------------------ --------------------------------- -------------------- - [Previous](11-06.html) [Table of Contents](index.html) [Next](11-08.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +can be used in some way to replace **POPF**. \ No newline at end of file diff --git a/11-08.md b/11-08.md index c2c0e29..23075d5 100644 --- a/11-08.md +++ b/11-08.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](11-07.html) [Table of Contents](index.html) [Next](12-01.html) - ------------------------ --------------------------------- -------------------- - Well, there's only one instruction other than **POPF** that loads the FLAGS register directly from the stack, and that's **IRET**, which loads the FLAGS register from the stack as it branches, as shown in Figure @@ -112,12 +108,4 @@ it occurs.) And now you know the nature of and the workaround for the **POPF** bug. Whether you ever need the workaround or not, it's a neatly packaged -example of the tremendous flexibility of the x86 instruction set. - - ------------------------ --------------------------------- -------------------- - [Previous](11-07.html) [Table of Contents](index.html) [Next](12-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +example of the tremendous flexibility of the x86 instruction set. \ No newline at end of file diff --git a/12-01.md b/12-01.md index 4b6ab9c..7d076fa 100644 --- a/12-01.md +++ b/12-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](11-08.html) [Table of Contents](index.html) [Next](12-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 12\ Pushing the 486 {#Heading1} ---------------- @@ -129,11 +125,3 @@ with this dec cx jnz LoopTop sub si,bx - - ------------------------ --------------------------------- -------------------- - [Previous](11-08.html) [Table of Contents](index.html) [Next](12-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/12-02.md b/12-02.md index 8ed43a7..c075642 100644 --- a/12-02.md +++ b/12-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](12-01.html) [Table of Contents](index.html) [Next](12-03.html) - ------------------------ --------------------------------- -------------------- - which calculates the same sum and leaves the registers in the same state as the first example, but avoids indexed addressing. @@ -150,12 +146,4 @@ penalty someday; likewise for the undocumented optimizations I'll describe below. Nonetheless, none of the optimizations I suggest would hurt performance even if the undocumented performance characteristics of the 486 were to vanish, and they certainly will help performance on at -least some 486s right now, so I feel they're well worth using. - - ------------------------ --------------------------------- -------------------- - [Previous](12-01.html) [Table of Contents](index.html) [Next](12-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +least some 486s right now, so I feel they're well worth using. \ No newline at end of file diff --git a/12-03.md b/12-03.md index 4d9c816..7c77874 100644 --- a/12-03.md +++ b/12-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](12-02.html) [Table of Contents](index.html) [Next](12-04.html) - ------------------------ --------------------------------- -------------------- - There is, of course, no guarantee that I'm entirely correct about the optimizations discussed in this chapter. Without knowing the internals of the 486, all I can do is time code and make inferences from the @@ -150,12 +146,4 @@ the performance dependencies, and I don't plan to; figuring all of them out would be a big, boring job of little value. Basically, on the 486 you should concentrate on using those fast core instructions when performance matters, and all the rules I'll discuss do indeed apply to -those instructions. - - ------------------------ --------------------------------- -------------------- - [Previous](12-02.html) [Table of Contents](index.html) [Next](12-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +those instructions. \ No newline at end of file diff --git a/12-04.md b/12-04.md index 55c06a9..ad34b8a 100644 --- a/12-04.md +++ b/12-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](12-03.html) [Table of Contents](index.html) [Next](13-01.html) - ------------------------ --------------------------------- -------------------- - You don't need to understand every corner of the 486 universe unless you're a diehard ASMhead who does this stuff for fun. Just learn enough to be able to speed up the key portions of your programs, and spend the @@ -153,12 +149,4 @@ staggeringly fast that carefully crafted 486 code can do more than twice as much per cycle as the best 386 code—which makes it perhaps 50 times as fast as optimized code for the original PC. -Sometimes it *is* hard to believe we're still in Kansas! - - ------------------------ --------------------------------- -------------------- - [Previous](12-03.html) [Table of Contents](index.html) [Next](13-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +Sometimes it *is* hard to believe we're still in Kansas! \ No newline at end of file diff --git a/13-01.md b/13-01.md index 03a4306..df051d1 100644 --- a/13-01.md +++ b/13-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](12-04.html) [Table of Contents](index.html) [Next](13-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 13\ Aiming the 486 {#Heading1} --------------- @@ -115,12 +111,4 @@ At this point, Terje had nearly doubled the performance of this code simply by moving one instruction. (Note that swapping the instructions also made it necessary to preload DI at the start of the loop; Listing 13.2 is not exactly equivalent to Listing 13.1.) I'll let Terje describe -his next optimization in his own words: - - ------------------------ --------------------------------- -------------------- - [Previous](12-04.html) [Table of Contents](index.html) [Next](13-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +his next optimization in his own words: \ No newline at end of file diff --git a/13-02.md b/13-02.md index df61863..ce0420f 100644 --- a/13-02.md +++ b/13-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](13-01.html) [Table of Contents](index.html) [Next](13-03.html) - ------------------------ --------------------------------- -------------------- - "When I looked closely as this, I realized that the two cycles for the final **ADD** is just the sum of 1 cycle to load the data from memory, and 1 cycle to add it to DX, so the code could just as well have been @@ -108,12 +104,4 @@ or from memory takes only one cycle. Basically, using **ROR** to access a 16-bit value in the upper half of a 16-bit register is a pretty marginal technique, unless for some reason you can't access memory at all (for example, if you're using BP as a working register, temporarily -making the stack frame inaccessible). - - ------------------------ --------------------------------- -------------------- - [Previous](13-01.html) [Table of Contents](index.html) [Next](13-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +making the stack frame inaccessible). \ No newline at end of file diff --git a/13-03.md b/13-03.md index a6806bc..e97f484 100644 --- a/13-03.md +++ b/13-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](13-02.html) [Table of Contents](index.html) [Next](13-04.html) - ------------------------ --------------------------------- -------------------- - On the 386, **ROR** was the only way to split a 32-bit register into two 16-bit registers. On the 486, however, **BSWAP** can not only do the job, but can do it better, because **BSWAP** executes in just one cycle. @@ -102,12 +98,4 @@ slow. But if you're optimizing for the 486, these tidbits can save a few critical cycles—and Lord knows that if you're optimizing for the 486—that is, if you need even more performance than you get from unoptimized code on a 486—you almost certainly need all the speed you -can get. - - ------------------------ --------------------------------- -------------------- - [Previous](13-02.html) [Table of Contents](index.html) [Next](13-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +can get. \ No newline at end of file diff --git a/13-04.md b/13-04.md index 835202c..e17980f 100644 --- a/13-04.md +++ b/13-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](13-03.html) [Table of Contents](index.html) [Next](14-01.html) - ------------------------ --------------------------------- -------------------- - ### 32-Bit Addressing Modes {#Heading7} The 386 and 486 both support 32-bit addressing modes, in which any @@ -103,12 +99,4 @@ capabilities of the Mod-R/M byte, and there's nothing to be done about it, but it's at least worth noting that ESP-based, non-indexed addressing makes for instructions that are a byte larger than other non-indexed addressing (but not any slower; there's no 1-cycle penalty -for using ESP as a base register) on the 486. - - ------------------------ --------------------------------- -------------------- - [Previous](13-03.html) [Table of Contents](index.html) [Next](14-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +for using ESP as a base register) on the 486. \ No newline at end of file diff --git a/14-01.md b/14-01.md index d39c61d..aff6030 100644 --- a/14-01.md +++ b/14-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](13-04.html) [Table of Contents](index.html) [Next](14-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 14\ Boyer-Moore String Searching {#Heading1} ----------------------------- @@ -122,12 +118,4 @@ character in turn. In order to get any faster, we'd have to check fewer characters—but we can't do that and still be sure of finding all matches. Can we? -Actually, yes, we can. - - ------------------------ --------------------------------- -------------------- - [Previous](13-04.html) [Table of Contents](index.html) [Next](14-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +Actually, yes, we can. \ No newline at end of file diff --git a/14-02.md b/14-02.md index ede43b4..c918379 100644 --- a/14-02.md +++ b/14-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](14-01.html) [Table of Contents](index.html) [Next](14-03.html) - ------------------------ --------------------------------- -------------------- - ### The Boyer-Moore Algorithm {#Heading4} All our *a priori* knowledge of string searching is stated above, but @@ -117,12 +113,4 @@ skip ahead on all the possible mismatch values. The best case for Boyer-Moore is good indeed: About N/M comparisons are required, where N is the buffer length and M is the pattern length. This reflects the ability of Boyer-Moore to skip ahead by a full pattern -length on a complete mismatch. - - ------------------------ --------------------------------- -------------------- - [Previous](14-01.html) [Table of Contents](index.html) [Next](14-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +length on a complete mismatch. \ No newline at end of file diff --git a/14-03.md b/14-03.md index 7444981..c7d2efe 100644 --- a/14-03.md +++ b/14-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](14-02.html) [Table of Contents](index.html) [Next](14-04.html) - ------------------------ --------------------------------- -------------------- - How fast *is* Boyer-Moore? Listing 14.1 is a C implementation of Boyer-Moore searching; Listing 14.2 is a test-bed program that searches up to the first 32K of a file for a pattern. Table 14.1 (all times @@ -147,12 +143,4 @@ in most cases than **REPNZ SCASB.** I say this casually now, but not so yesterday, when I had all but concluded that Boyer-Moore was simply inferior on the x86, due to two architectural quirks: the string instructions and slow branch. I had even coined a neat phrase for it: -Architecture is destiny. Has a nice ring, doesn't it? - - ------------------------ --------------------------------- -------------------- - [Previous](14-02.html) [Table of Contents](index.html) [Next](14-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +Architecture is destiny. Has a nice ring, doesn't it? \ No newline at end of file diff --git a/14-04.md b/14-04.md index 9f0ae3e..f0ed3ec 100644 --- a/14-04.md +++ b/14-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](14-03.html) [Table of Contents](index.html) [Next](14-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 14.1 L14-1.C** /* Searches a buffer for a specified pattern. In case of a mismatch, @@ -162,12 +158,4 @@ Table 14.1 speak for themselves; Listing 14.3 is more than twice as fast as what I assure you was already a nice, tight assembly implementation (and unrolling **QuickSearchLoop** could boost performance by up to 10 percent more). Listing 14.3 is also *four times* faster than **REPNZ -SCASB** in one case. - - ------------------------ --------------------------------- -------------------- - [Previous](14-03.html) [Table of Contents](index.html) [Next](14-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +SCASB** in one case. \ No newline at end of file diff --git a/14-05.md b/14-05.md index b17d552..e984b42 100644 --- a/14-05.md +++ b/14-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](14-04.html) [Table of Contents](index.html) [Next](14-06.html) - ------------------------ --------------------------------- -------------------- - **LISTING 14.3 L14-3.ASM** ; Searches a buffer for a specified pattern. In case of a mismatch, @@ -164,11 +160,3 @@ ret _FindString endp end - - ------------------------ --------------------------------- -------------------- - [Previous](14-04.html) [Table of Contents](index.html) [Next](14-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/14-06.md b/14-06.md index 1f74e36..a18decb 100644 --- a/14-06.md +++ b/14-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](14-05.html) [Table of Contents](index.html) [Next](15-01.html) - ------------------------ --------------------------------- -------------------- - Table 14.1 represents a limited and decidedly unscientific comparison of searching techniques. Nonetheless, the overall trend is clear: For all but the shortest patterns, well-implemented Boyer-Moore is generally as @@ -190,12 +186,4 @@ Everything we needed was sitting there all along; we just needed to think to look at it. As Yogi Berra might put it, "You don't know what you know until you know -it." - - ------------------------ --------------------------------- -------------------- - [Previous](14-05.html) [Table of Contents](index.html) [Next](15-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +it." \ No newline at end of file diff --git a/15-01.md b/15-01.md index a0e1834..6cb723b 100644 --- a/15-01.md +++ b/15-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](14-06.html) [Table of Contents](index.html) [Next](15-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 15\ Linked Lists and plain Unintended Challenges {#Heading1} --------------------------------------------- @@ -140,12 +136,4 @@ structure—but that's an ugly and potentially dangerous trick, and we'll see a better approach next.) ![](images/15-01.jpg)\ - **Figure 15.1**  *The basic concept of a linked list.* - - ------------------------ --------------------------------- -------------------- - [Previous](14-06.html) [Table of Contents](index.html) [Next](15-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash + **Figure 15.1**  *The basic concept of a linked list.* \ No newline at end of file diff --git a/15-02.md b/15-02.md index a7e1d2a..bbe469d 100644 --- a/15-02.md +++ b/15-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](15-01.html) [Table of Contents](index.html) [Next](15-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 15.1 L15-1.C** /* Deletes the node in a linked list that follows the indicated node. @@ -151,12 +147,4 @@ themselves to sentinels, but the performance benefits are considerable for those that do. ![](images/15-03.jpg)\ - **Figure 15.3**  *Representing an empty list.* - - ------------------------ --------------------------------- -------------------- - [Previous](15-01.html) [Table of Contents](index.html) [Next](15-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash + **Figure 15.3**  *Representing an empty list.* \ No newline at end of file diff --git a/15-03.md b/15-03.md index 3506a7c..724d447 100644 --- a/15-03.md +++ b/15-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](15-02.html) [Table of Contents](index.html) [Next](15-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 15.5 L15-5.C** /* Finds the first node in a value-sorted linked list that @@ -139,11 +135,3 @@ before you write a single line of code. NodePtr->NextNode = NodeToInsert; return(NodePtr); } - - ------------------------ --------------------------------- -------------------- - [Previous](15-02.html) [Table of Contents](index.html) [Next](15-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/15-04.md b/15-04.md index 5f04fe1..54f8b48 100644 --- a/15-04.md +++ b/15-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](15-03.html) [Table of Contents](index.html) [Next](16-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 15.7 L15-7.ASM** ; C near-callable assembly function for inserting a new node in a @@ -205,12 +201,4 @@ reads closely enough. Before I end this chapter, let me say that I get a lot of feedback from my readers, and it's much appreciated. Keep those cards, letters, and email messages coming. And if any of you know Jeannie Schweigert, have -her drop me a line and let me know how she's doing these days.... - - ------------------------ --------------------------------- -------------------- - [Previous](15-03.html) [Table of Contents](index.html) [Next](16-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +her drop me a line and let me know how she's doing these days.... \ No newline at end of file diff --git a/16-01.md b/16-01.md index f21330f..d1de0c5 100644 --- a/16-01.md +++ b/16-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](15-04.html) [Table of Contents](index.html) [Next](16-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 16\ There Ain't No Such Thing as the Fastest Code {#Heading1} ---------------------------------------------- @@ -179,12 +175,3 @@ Table 16.1 Word count timings. printf("\nTotal words in file: %lu\n", WordCount); return(0); } - - - ------------------------ --------------------------------- -------------------- - [Previous](15-04.html) [Table of Contents](index.html) [Next](16-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/16-02.md b/16-02.md index 86f7549..97fbde9 100644 --- a/16-02.md +++ b/16-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](16-01.html) [Table of Contents](index.html) [Next](16-03.html) - ------------------------ --------------------------------- -------------------- - Listing 16.2 is Listing 16.1 modified to call a function that scans each block for words, and Listing 16.3 contains an assembly function that counts words. Used together, Listings 16.2 and 16.3 are just about twice @@ -174,12 +170,4 @@ times the performance of the original C code. On a 20 MHz 386, this represents a change from 4.6 to 1.6 seconds, which could be significant—who likes to wait? On an 8088, the improvement in word-counting a large file could easily be 10 or 20 seconds, which is -*definitely* significant. - - ------------------------ --------------------------------- -------------------- - [Previous](16-01.html) [Table of Contents](index.html) [Next](16-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +*definitely* significant. \ No newline at end of file diff --git a/16-03.md b/16-03.md index 88a5cfe..c8e3b21 100644 --- a/16-03.md +++ b/16-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](16-02.html) [Table of Contents](index.html) [Next](16-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 16.4 L16-4.ASM** ; Assembly subroutine for Listing 16.2. Scans through Buffer, of @@ -158,12 +154,4 @@ one claimed a speed-up over my assembly word-counting code of more than three times. On top of the three-times speedup over the original C code that I had already realized, we're almost up to an order of magnitude faster. You are, of course, entitled to your own opinion, but *I* -consider an order of magnitude to be significant. - - ------------------------ --------------------------------- -------------------- - [Previous](16-02.html) [Table of Contents](index.html) [Next](16-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +consider an order of magnitude to be significant. \ No newline at end of file diff --git a/16-04.md b/16-04.md index a0a393c..0b064c7 100644 --- a/16-04.md +++ b/16-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](16-03.html) [Table of Contents](index.html) [Next](16-05.html) - ------------------------ --------------------------------- -------------------- - Truth to tell, I didn't expect a three-times speedup; around two times was what I had in mind. Which just goes to show that any code can be made faster than you'd expect, if you think about it long enough and @@ -129,12 +125,4 @@ programmer, was a close third, as shown in Table 16.2, which precedes Listing 16.5. Those three were out ahead of the pack; the fourth-place entry, good as it was (twice as fast as my original code), was twice as slow as David's winning entry, so you can see that David, Dave, and Mick -attained a rarefied level of optimization indeed. - - ------------------------ --------------------------------- -------------------- - [Previous](16-03.html) [Table of Contents](index.html) [Next](16-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +attained a rarefied level of optimization indeed. \ No newline at end of file diff --git a/16-05.md b/16-05.md index a53a334..369b6d7 100644 --- a/16-05.md +++ b/16-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](16-04.html) [Table of Contents](index.html) [Next](16-06.html) - ------------------------ --------------------------------- -------------------- - Table 16.2 has two times for each entry listed: the first value is the overall counting time, including time spent in the main program, disk I/O, and everything else; the second value is the time actually spent @@ -254,11 +250,3 @@ Table 16.2 The top four word-counting entries. .fardata WordTable include qscan3.inc ;built by MAKETAB end - - ------------------------ --------------------------------- -------------------- - [Previous](16-04.html) [Table of Contents](index.html) [Next](16-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/16-06.md b/16-06.md index 9c160b4..c159224 100644 --- a/16-06.md +++ b/16-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](16-05.html) [Table of Contents](index.html) [Next](16-07.html) - ------------------------ --------------------------------- -------------------- - ### Levels of Optimization {#Heading9} Three levels of optimization were evident in the word-counting entries I @@ -80,12 +76,4 @@ short, this is an excellent example of how an hour or so of hand-optimization might accomplish significantly improved performance at a reasonable cost in complexity and time. This level of optimization is adequate for most purposes (and, in truth, is beyond the abilities of -most programmers). - - ------------------------ --------------------------------- -------------------- - [Previous](16-05.html) [Table of Contents](index.html) [Next](16-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +most programmers). \ No newline at end of file diff --git a/16-07.md b/16-07.md index d62692b..324026f 100644 --- a/16-07.md +++ b/16-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](16-06.html) [Table of Contents](index.html) [Next](16-08.html) - ------------------------ --------------------------------- -------------------- - **Listing 16.6 OPT2.ASM** ; @@ -160,12 +156,4 @@ were really looking at an edge triggered device we want to count each time the I'm a character state goes from one to zero. Remembering that XOR on two single-bit values will always return whether the bits are different or the same, I implemented a transition counter. The counter -triggers every time a word begins or ends."* - - ------------------------ --------------------------------- -------------------- - [Previous](16-06.html) [Table of Contents](index.html) [Next](16-08.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +triggers every time a word begins or ends."* \ No newline at end of file diff --git a/16-08.md b/16-08.md index 6bfb2c8..8915202 100644 --- a/16-08.md +++ b/16-08.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](16-07.html) [Table of Contents](index.html) [Next](17-01.html) - ------------------------ --------------------------------- -------------------- - **Listing 16.7 L16-7.ASM** ScanLoop: @@ -163,12 +159,4 @@ that calculates the theoretical maximum performance of native 386 word-counting code at 5.5 cycles/byte, which would be significantly faster than David's code. Terry, alas, didn't bother to implement his design, but maybe I'll take a shot at it someday. It'd be fun, for -sure—but jeez, I've got *real* work to do! - - ------------------------ --------------------------------- -------------------- - [Previous](16-07.html) [Table of Contents](index.html) [Next](17-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +sure—but jeez, I've got *real* work to do! \ No newline at end of file diff --git a/17-01.md b/17-01.md index 87b6d26..910a389 100644 --- a/17-01.md +++ b/17-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](16-08.html) [Table of Contents](index.html) [Next](17-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 17\ The Game of Life {#Heading1} ----------------- @@ -90,12 +86,4 @@ we're done using it to calculate the next generation. All in all, Listing 17.1 is a clean, compact, and elegant implementation of the Game of Life. Were it not that the code is as slow as molasses, -we could stop right here. - - ------------------------ --------------------------------- -------------------- - [Previous](16-08.html) [Table of Contents](index.html) [Next](17-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +we could stop right here. \ No newline at end of file diff --git a/17-02.md b/17-02.md index 02e9718..89d5578 100644 --- a/17-02.md +++ b/17-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](17-01.html) [Table of Contents](index.html) [Next](17-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 17.1 L17-1.CPP** /* C++ Game of Life implementation for any mode for which mode set @@ -257,11 +253,3 @@ gotoxy(TEXT_X_OFFSET + x, y); puts(text); } - - ------------------------ --------------------------------- -------------------- - [Previous](17-01.html) [Table of Contents](index.html) [Next](17-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/17-03.md b/17-03.md index 9925aa6..cb7a5fe 100644 --- a/17-03.md +++ b/17-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](17-02.html) [Table of Contents](index.html) [Next](17-04.html) - ------------------------ --------------------------------- -------------------- - ### Where Does the Time Go? {#Heading5} How slow is Listing 17.1? Table 17.1 shows that even on a 486, Listing @@ -157,12 +153,4 @@ with eight completely independent operations, requiring eight calls to In fact, given the nature of cell storage, the eight neighbors are in a fixed relationship to one another, and the addresses and masks of all eight can generally be found very easily via hard-wired offsets and -shifts once the address and mask of any one is known. - - ------------------------ --------------------------------- -------------------- - [Previous](17-02.html) [Table of Contents](index.html) [Next](17-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +shifts once the address and mask of any one is known. \ No newline at end of file diff --git a/17-04.md b/17-04.md index 2f1d039..60b787a 100644 --- a/17-04.md +++ b/17-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](17-03.html) [Table of Contents](index.html) [Next](17-05.html) - ------------------------ --------------------------------- -------------------- - There's a kicker here, though, and that's the counting of neighbors for cells at the edge of the cellmap. When cellmap wrapping is enabled (so that the cellmap becomes essentially a toroid, with each edge joined @@ -203,11 +199,3 @@ improvement. } } } - - ------------------------ --------------------------------- -------------------- - [Previous](17-03.html) [Table of Contents](index.html) [Next](17-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/17-05.md b/17-05.md index 801283e..47f7ebb 100644 --- a/17-05.md +++ b/17-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](17-04.html) [Table of Contents](index.html) [Next](17-06.html) - ------------------------ --------------------------------- -------------------- - In Listing 17.3, note the padded cellmap edges, and the alteration of the member functions to compensate for the padding. Also note that the width now has to be a multiple of eight, to facilitate the process of @@ -153,12 +149,4 @@ possible that way. ------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ![](images/i.jpg) *Once you've reached the point of fine-tuning pointer usage and register variables and the like in C or C++, you've become compiler-dependent; you therefore might as well go to assembly and get the real McCoy.* - ------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - ------------------------ --------------------------------- -------------------- - [Previous](17-04.html) [Table of Contents](index.html) [Next](17-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash + ------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/17-06.md b/17-06.md index 53cceb0..4f100bb 100644 --- a/17-06.md +++ b/17-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](17-05.html) [Table of Contents](index.html) [Next](17-07.html) - ------------------------ --------------------------------- -------------------- - We're still not ready for assembly, though; what we need is a new perspective that lends itself to vastly better performance in C++. The Life program in the next section is *three to seven times* faster than @@ -117,12 +113,4 @@ time consumed by drawing and text display) than Listing 17.4, which is no slouch. On a 33 MHz 486, Listing 17.5 is about 3.5 times faster than Listing 17.4. This is true even though Listing 17.5 must be compiled using the large model. Imagine that—getting a four times speed-up while -switching from the small model to the large model! - - ------------------------ --------------------------------- -------------------- - [Previous](17-05.html) [Table of Contents](index.html) [Next](17-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +switching from the small model to the large model! \ No newline at end of file diff --git a/17-07.md b/17-07.md index afc0da0..23bb229 100644 --- a/17-07.md +++ b/17-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](17-06.html) [Table of Contents](index.html) [Next](17-08.html) - ------------------------ --------------------------------- -------------------- - **LISTING 17.5 L17-5.CPP** /* C++ Game of Life implementation for any mode for which mode set @@ -277,11 +273,3 @@ } } while (—init_length); } - - ------------------------ --------------------------------- -------------------- - [Previous](17-06.html) [Table of Contents](index.html) [Next](17-08.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/17-08.md b/17-08.md index 4c770f0..00d6d75 100644 --- a/17-08.md +++ b/17-08.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](17-07.html) [Table of Contents](index.html) [Next](18-01.html) - ------------------------ --------------------------------- -------------------- - The large model is actually not necessary for the 96x96 cellmap in Listing 17.5. However, I was actually more interested in seeing a fast 200x200 cellmap, and two 200x200 cellmaps can't fit in a single segment. @@ -75,12 +71,4 @@ for adherence to the rules, read, compiled, linked, run, and judged. I learned a lot—about a lot of things, not the least of which was the process (or maybe the wisdom) of laying down challenges to readers. -Who won? What did I learn? To find out, read on. - - ------------------------ --------------------------------- -------------------- - [Previous](17-07.html) [Table of Contents](index.html) [Next](18-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +Who won? What did I learn? To find out, read on. \ No newline at end of file diff --git a/18-01.md b/18-01.md index dd3fdff..f721069 100644 --- a/18-01.md +++ b/18-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](17-08.html) [Table of Contents](index.html) [Next](18-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 18\ It's a plain Wonderful Life {#Heading1} ---------------------------- @@ -102,11 +98,3 @@ specific "you" may or may not be quite up to the optimizing level of the specific "David Stafford" or "Peter Klerings.") Onward to the code. - - ------------------------ --------------------------------- -------------------- - [Previous](17-08.html) [Table of Contents](index.html) [Next](18-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/18-02.md b/18-02.md index 5c267d1..cdbd35a 100644 --- a/18-02.md +++ b/18-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](18-01.html) [Table of Contents](index.html) [Next](18-03.html) - ------------------------ --------------------------------- -------------------- - ### Table-Driven Magic {#Heading4} David Stafford won my first Optimization Challenge by means of a huge @@ -80,11 +76,3 @@ visualize its operation without actually seeing it. > —*David Stafford* > > * * * * * - - ------------------------ --------------------------------- -------------------- - [Previous](18-01.html) [Table of Contents](index.html) [Next](18-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/18-03.md b/18-03.md index 3f38d54..1c55f63 100644 --- a/18-03.md +++ b/18-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](18-02.html) [Table of Contents](index.html) [Next](18-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 18.1 BUILD.BAT** bcc -v -D%1=%2;%2=%3;%3=%4;%4=%5;%5=%6;%6=%7;%7=%8;%8 lcomp.c @@ -504,11 +500,3 @@ printf( "LIFE ends\nend\n" ); } - - ------------------------ --------------------------------- -------------------- - [Previous](18-02.html) [Table of Contents](index.html) [Next](18-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/18-04.md b/18-04.md index 5dec62e..5754801 100644 --- a/18-04.md +++ b/18-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](18-03.html) [Table of Contents](index.html) [Next](18-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 18.3 MAIN.C** // MAIN.C @@ -200,12 +196,4 @@ never needs to reflect more than seven neighbors, because at least one of the eight neighbors' states is already encoded in the word.] ![](images/18-01.jpg)\ - **Figure 18.1**  *Cell triplet storage.* - - ------------------------ --------------------------------- -------------------- - [Previous](18-03.html) [Table of Contents](index.html) [Next](18-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash + **Figure 18.1**  *Cell triplet storage.* \ No newline at end of file diff --git a/18-05.md b/18-05.md index cc8f36b..baff8e2 100644 --- a/18-05.md +++ b/18-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](18-04.html) [Table of Contents](index.html) [Next](19-01.html) - ------------------------ --------------------------------- -------------------- - "The basic idea is to maintain a ‘change list.' This is an array of pointers into the cell array. Each change list element points to a word which changes in the next generation. This way we don't have to waste @@ -112,12 +108,4 @@ my pleasure to meet, who, after looking over David's and Peter's entries, said, "This has been an eye-opening experience for me. I honestly thought I had the fastest possible approach." TANSTATFC. -There Ain't No Such Thing As the Fastest Code. - - ------------------------ --------------------------------- -------------------- - [Previous](18-04.html) [Table of Contents](index.html) [Next](19-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash +There Ain't No Such Thing As the Fastest Code. \ No newline at end of file diff --git a/19-01.md b/19-01.md index c0307aa..fee48fb 100644 --- a/19-01.md +++ b/19-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](18-05.html) [Table of Contents](index.html) [Next](19-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 19\ Pentium: Not the Same Old Song {#Heading1} ------------------------------- @@ -115,11 +111,3 @@ answer is: rarely indeed, and then only because the code is not in the internal cache. The 486 has a single 8K cache that stores both code and data, and prefetching can stall if data fetching doesn't allow time for prefetching to occur (although this rarely happens in practice). - - ------------------------ --------------------------------- -------------------- - [Previous](18-05.html) [Table of Contents](index.html) [Next](19-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/19-02.md b/19-02.md index 4fd72af..2a860bc 100644 --- a/19-02.md +++ b/19-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](19-01.html) [Table of Contents](index.html) [Next](19-03.html) - ------------------------ --------------------------------- -------------------- - ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ![](images/i.jpg) *The Pentium, on the other hand, has two separate 8K caches, one for code and one for data, so code prefetches can never collide with data fetches; the prefetch queue can stall only when the code being fetched isn't in the internal code cache.* ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ @@ -112,11 +108,3 @@ makes it functionally identical, but cuts the cycles to 2—a 50 percent improvement. Clearly, avoiding AGIs becomes a much more challenging and rewarding game in a superscalar world, one to which I'll return in the next chapter. - - ------------------------ --------------------------------- -------------------- - [Previous](19-01.html) [Table of Contents](index.html) [Next](19-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/19-03.md b/19-03.md index ddb462e..dd02da3 100644 --- a/19-03.md +++ b/19-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](19-02.html) [Table of Contents](index.html) [Next](19-04.html) - ------------------------ --------------------------------- -------------------- - ### Faster Addressing and More {#Heading7} I'll spend the rest of this chapter covering a variety of Pentium @@ -92,11 +88,3 @@ that ahead of time, so if **AND** or **OR** goes through the U-pipe, the Pentium may have to shut down the V-pipe for a cycle to avoid potential dependencies on the result of the **AND** or **OR**. **TEST** suffers from no such potential dependencies. - - ------------------------ --------------------------------- -------------------- - [Previous](19-02.html) [Table of Contents](index.html) [Next](19-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/19-04.md b/19-04.md index 1893893..3e5709b 100644 --- a/19-04.md +++ b/19-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](19-03.html) [Table of Contents](index.html) [Next](20-01.html) - ------------------------ --------------------------------- -------------------- - ### Branch Prediction {#Heading8} One brand-spanking-new feature of the Pentium is *branch prediction*, @@ -115,11 +111,3 @@ optimizers. A compiler that generates better code than a good assembly programmer? That'll be the day. - - ------------------------ --------------------------------- -------------------- - [Previous](19-03.html) [Table of Contents](index.html) [Next](20-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/20-01.md b/20-01.md index 91e3818..b5dfede 100644 --- a/20-01.md +++ b/20-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](19-04.html) [Table of Contents](index.html) [Next](20-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 20\ Pentium Rules {#Heading1} -------------- @@ -128,11 +124,3 @@ as possible, instruction mixes that take the V-pipe out of action. In practice, this is not too difficult. The only hard part is keeping in mind the long list of rules governing instruction pairing. The place to begin is with the set of instructions that can go through the V-pipe. - - ------------------------ --------------------------------- -------------------- - [Previous](19-04.html) [Table of Contents](index.html) [Next](20-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/20-02.md b/20-02.md index ada0762..49aebfd 100644 --- a/20-02.md +++ b/20-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](20-01.html) [Table of Contents](index.html) [Next](20-03.html) - ------------------------ --------------------------------- -------------------- - ### V-Pipe-Capable Instructions {#Heading4} Any instruction can go through the U-pipe, and, for practical purposes, @@ -180,11 +176,3 @@ sequence can be reduced to 1.5 cycles, but it is *14* bytes long. ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ![](images/i.jpg) *It's not unusual for Pentium optimization to approximately double both performance and code size at the same time. In an important loop, go for performance and ignore the size, but on a program-wide basis, the size bears watching.* ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - - ------------------------ --------------------------------- -------------------- - [Previous](20-01.html) [Table of Contents](index.html) [Next](20-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/20-03.md b/20-03.md index daec678..d48f52e 100644 --- a/20-03.md +++ b/20-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](20-02.html) [Table of Contents](index.html) [Next](20-04.html) - ------------------------ --------------------------------- -------------------- - ### Lockstep Execution {#Heading5} You may wonder why anyone would bother breaking **ADD [MemVar],EAX** @@ -110,11 +106,3 @@ these: add esi,[SourceSkip] ;U-pipe cycles 1 and 2 add edi,[DestinationSkip] ;V-pipe cycles 1 and 2 - - ------------------------ --------------------------------- -------------------- - [Previous](20-02.html) [Table of Contents](index.html) [Next](20-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/20-04.md b/20-04.md index ccf370d..295fa25 100644 --- a/20-04.md +++ b/20-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](20-03.html) [Table of Contents](index.html) [Next](21-01.html) - ------------------------ --------------------------------- -------------------- - However, this beneficial pairing does not extend to non-**MOV** instructions with explicit memory destination operands, such as **ADD [EBX],EAX**. The Pentium executes only one such memory instruction at a @@ -113,11 +109,3 @@ you measure it! ![](images/20-08.jpg)\ **Figure 20.8**  *Prefix delays.* - - ------------------------ --------------------------------- -------------------- - [Previous](20-03.html) [Table of Contents](index.html) [Next](21-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/21-01.md b/21-01.md index 5cd6594..840c4ee 100644 --- a/21-01.md +++ b/21-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](20-04.html) [Table of Contents](index.html) [Next](21-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 21\ Unleashing the Pentium's V-Pipe {#Heading1} -------------------------------- @@ -115,11 +111,3 @@ Pentium doesn't know that, so it has to insert the AGI. ![](images/21-02.jpg)\ **Figure 21.2**  *An AGI can cost as many as 3 cycles.* - - ------------------------ --------------------------------- -------------------- - [Previous](20-04.html) [Table of Contents](index.html) [Next](21-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/21-02.md b/21-02.md index 16ba385..ed6a7e9 100644 --- a/21-02.md +++ b/21-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](21-01.html) [Table of Contents](index.html) [Next](21-03.html) - ------------------------ --------------------------------- -------------------- - As on the 486, you should keep a careful eye out for AGIs involving the stack pointer. Implicit modifiers of ESP, such as **PUSH** and **POP**, are special-cased so you don't have to worry about AGIs. However, if you @@ -160,11 +156,3 @@ even though we only added 25 percent more cycles: ;V-pipe idle cycle 3 ; because JNZ can't ; pair in the U-pipe - - ------------------------ --------------------------------- -------------------- - [Previous](21-01.html) [Table of Contents](index.html) [Next](21-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/21-03.md b/21-03.md index 0ad094c..5fe52be 100644 --- a/21-03.md +++ b/21-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](21-02.html) [Table of Contents](index.html) [Next](21-04.html) - ------------------------ --------------------------------- -------------------- - It's actually not hard to figure out which instructions go through which pipes; just back up until you find an instruction that can't pair or can only go through the U-pipe, and work forward from there, given the @@ -86,11 +82,3 @@ is that prefixes can pair with the first cycle of at least some multiple-cycle instructions. Determining exactly why this happens will take further research on my part, but the most important conclusion is that you *must* measure your code! - - ------------------------ --------------------------------- -------------------- - [Previous](21-02.html) [Table of Contents](index.html) [Next](21-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/21-04.md b/21-04.md index 3c2ff4c..ec4af68 100644 --- a/21-04.md +++ b/21-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](21-03.html) [Table of Contents](index.html) [Next](21-05.html) - ------------------------ --------------------------------- -------------------- - The first, obvious thing we can do to Listing 21.1 is change **ADC AX,0** to **ADC EAX,0**, eliminating a prefix byte and saving a full cycle. Now we're down from five to four cycles. What next? @@ -138,11 +134,3 @@ code: three cycles per loop, or 1.5 cycles per checksummed word, more than three times the speed of the original code. Again, note that the actual order in which the instructions are arranged is dictated by the various optimization hazards of the Pentium. - - ------------------------ --------------------------------- -------------------- - [Previous](21-03.html) [Table of Contents](index.html) [Next](21-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/21-05.md b/21-05.md index f7b2866..ef2bfe7 100644 --- a/21-05.md +++ b/21-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](21-04.html) [Table of Contents](index.html) [Next](22-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 21.4 L21-4.ASM** ; Calculates TCP/IP (16-bit carry-wrapping) checksum for buffer @@ -118,11 +114,3 @@ cycles per word; Listing 21.5 runs at 7 cycles per word, a 3.1-times speedup. As is often the case, Pentium optimization helped the other processors, but not as much as it helped the Pentium, and less on the 386 than on the 486. - - ------------------------ --------------------------------- -------------------- - [Previous](21-04.html) [Table of Contents](index.html) [Next](22-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/22-01.md b/22-01.md index 2310406..f3fe6b8 100644 --- a/22-01.md +++ b/22-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](21-05.html) [Table of Contents](index.html) [Next](22-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 22\ Zenning and the Flexible Mind {#Heading1} ------------------------------ @@ -107,11 +103,3 @@ of better instructions for particular tasks than those that were chosen. For example, there's no need to load any register, whether segment or general, through BX; we can eliminate two instructions by loading ES and DI directly as shown in Listing 22.2. - - ------------------------ --------------------------------- -------------------- - [Previous](21-05.html) [Table of Contents](index.html) [Next](22-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/22-02.md b/22-02.md index 04c83f1..e5d5a5e 100644 --- a/22-02.md +++ b/22-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](22-01.html) [Table of Contents](index.html) [Next](22-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 22.2 L22-2.ASM** ClearS proc near @@ -108,11 +104,3 @@ another byte addressed relative to BP into AL. Heck, we can just do that directly! Presto—we've saved another 6 bytes, and turned two word-sized memory accesses into byte-sized memory accesses as well. Listing 22.5 shows the new code. - - ------------------------ --------------------------------- -------------------- - [Previous](22-01.html) [Table of Contents](index.html) [Next](22-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/22-03.md b/22-03.md index b8321ee..6c021f0 100644 --- a/22-03.md +++ b/22-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](22-02.html) [Table of Contents](index.html) [Next](23-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 22.5 L22-5.ASM** ClearS proc near @@ -122,11 +118,3 @@ and fewer memory accesses. All in all, the Zenned version of **ClearS** is a vast improvement over the original. Probably not the best possible implementation—*never say never!*—but an awfully good one. - - ------------------------ --------------------------------- -------------------- - [Previous](22-02.html) [Table of Contents](index.html) [Next](23-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/23-01.md b/23-01.md index 49b72fc..6a889e4 100644 --- a/23-01.md +++ b/23-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](22-03.html) [Table of Contents](index.html) [Next](23-02.html) - ------------------------ --------------------------------- -------------------- - *Part II* {align="center"} --------- @@ -121,11 +117,3 @@ manipulation, multi-plane block copying, and page flipping—at a conceptual level, letting the code itself demonstrate the implementation details. We'll return to many of these concepts in more depth later in this book. - - ------------------------ --------------------------------- -------------------- - [Previous](22-03.html) [Table of Contents](index.html) [Next](23-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/23-02.md b/23-02.md index 7dfe0d5..42916d8 100644 --- a/23-02.md +++ b/23-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](23-01.html) [Table of Contents](index.html) [Next](23-03.html) - ------------------------ --------------------------------- -------------------- - ### At the Core {#Heading5} A little background is necessary before we're ready to examine Listing @@ -166,11 +162,3 @@ fixed. Moreover, a great deal of graphics software now uses word -- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- *which is generally faster (and never slower) than a word-sized **OUT**, and which does not require AH to be set, freeing up a register. Of course, this method only works if the GC Index register remains unchanged throughout the loop.* -- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - ------------------------ --------------------------------- -------------------- - [Previous](23-01.html) [Table of Contents](index.html) [Next](23-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/23-03.md b/23-03.md index 01a94dc..5659d29 100644 --- a/23-03.md +++ b/23-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](23-02.html) [Table of Contents](index.html) [Next](23-04.html) - ------------------------ --------------------------------- -------------------- - #### Linear Planes and True VGA Modes {#Heading6} The VGA's memory is organized as four 64K planes. Each of these planes @@ -620,11 +616,3 @@ seen the features in action. AdjustPanning endp cseg ends end start - - ------------------------ --------------------------------- -------------------- - [Previous](23-02.html) [Table of Contents](index.html) [Next](23-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/23-04.md b/23-04.md index c52b064..cd5e0bf 100644 --- a/23-04.md +++ b/23-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](23-03.html) [Table of Contents](index.html) [Next](23-05.html) - ------------------------ --------------------------------- -------------------- - #### Smooth Panning {#Heading7} The first thing you'll notice upon running the sample program is the @@ -103,11 +99,3 @@ should be set to 1. ------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ![](images/i.jpg) *By the way, palette RAM can be set via the BIOS video interrupt (interrupt 10H), function 10H. Whenever an VGA function can be performed reasonably well through a BIOS function, as it can in the case of setting palette RAM, it should be, both because there is no point in reinventing the wheel and because the BIOS may well mask incompatibilities between the IBM VGA and VGA clones.* ------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - ------------------------ --------------------------------- -------------------- - [Previous](23-03.html) [Table of Contents](index.html) [Next](23-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/23-05.md b/23-05.md index dcf0f41..49f9595 100644 --- a/23-05.md +++ b/23-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](23-04.html) [Table of Contents](index.html) [Next](23-06.html) - ------------------------ --------------------------------- -------------------- - #### Color Plane Manipulation {#Heading8} The VGA provides a considerable amount of hardware assistance for @@ -130,11 +126,3 @@ because we might have the extreme misfortune to set one of the start address registers before the start of vertical sync and the other after, resulting in mismatched halves of the start address and a nasty jump of the displayed image for one frame. - - ------------------------ --------------------------------- -------------------- - [Previous](23-04.html) [Table of Contents](index.html) [Next](23-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/23-06.md b/23-06.md index 38be055..b1dbf2b 100644 --- a/23-06.md +++ b/23-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](23-05.html) [Table of Contents](index.html) [Next](24-01.html) - ------------------------ --------------------------------- -------------------- - One possible solution to this problem is to pick a second page start address that has a 0 value for the lower byte, so only the Start Address High register ever needs to be set, but in the sample program in Listing @@ -108,11 +104,3 @@ assistance the VGA provides the CPU during display memory access. There are four latches and four ALUs in those chips, along with some useful masks and comparators, and it's that hardware that's the difference between sluggish performance and making the VGA get up and dance. - - ------------------------ --------------------------------- -------------------- - [Previous](23-05.html) [Table of Contents](index.html) [Next](24-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/24-01.md b/24-01.md index 455bb17..bb56f6d 100644 --- a/24-01.md +++ b/24-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](23-06.html) [Table of Contents](index.html) [Next](24-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 24\ Parallel Processing with the VGA {#Heading1} --------------------------------- @@ -108,11 +104,3 @@ clearly. Selective enabling of planes via the Map Mask register and/or set/reset would produce color effects; in that case, the operation of the logical functions must be evaluated on a plane-by-plane basis, since only the enabled planes would be affected by each operation. - - ------------------------ --------------------------------- -------------------- - [Previous](23-06.html) [Table of Contents](index.html) [Next](24-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/24-02.md b/24-02.md index d35638c..cbc1402 100644 --- a/24-02.md +++ b/24-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](24-01.html) [Table of Contents](index.html) [Next](24-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 24.1 L24-1.ASM** ; Program to illustrate operation of ALUs and latches of the VGA's @@ -255,11 +251,3 @@ DrawVerticalBox endp cseg ends end start - - ------------------------ --------------------------------- -------------------- - [Previous](24-01.html) [Table of Contents](index.html) [Next](24-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/24-03.md b/24-03.md index 72c7718..7c5b58e 100644 --- a/24-03.md +++ b/24-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](24-02.html) [Table of Contents](index.html) [Next](25-01.html) - ------------------------ --------------------------------- -------------------- - Logical function 0, which writes the CPU data unmodified, is the standard mode of operation of the ALUs. In this mode, the CPU data is combined with the latched data by ignoring the latched data entirely. @@ -114,11 +110,3 @@ far more limited than a CPU. In many instances, however, additional hardware in the VGA, including the bit mask, the set/reset features, and the barrel shifter, can assist the ALUs in controlling data, as we'll see in the next few chapters. - - ------------------------ --------------------------------- -------------------- - [Previous](24-02.html) [Table of Contents](index.html) [Next](25-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/25-01.md b/25-01.md index 8b9d474..5070b5b 100644 --- a/25-01.md +++ b/25-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](24-03.html) [Table of Contents](index.html) [Next](25-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 25\ VGA Data Machinery {#Heading1} ------------------- @@ -96,11 +92,3 @@ and every 16 scan lines vertically. However, with direct bitmapped text drawing of the sort used in Listing 25.1, it's possible to draw any font of any size anywhere on the screen (and a lot faster than via DOS or the BIOS, as well). - - ------------------------ --------------------------------- -------------------- - [Previous](24-03.html) [Table of Contents](index.html) [Next](25-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/25-02.md b/25-02.md index 1a99423..44aa361 100644 --- a/25-02.md +++ b/25-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](25-01.html) [Table of Contents](index.html) [Next](25-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 25.1 L25-1.ASM** ; Program to illustrate operation of data rotate and bit mask @@ -249,11 +245,3 @@ pixels that are to be drawn, without interfering with the pixels that are to be left unchanged. The alternative would be plane-by-plane processing, which from a performance perspective would be undesirable indeed. - - ------------------------ --------------------------------- -------------------- - [Previous](25-01.html) [Table of Contents](index.html) [Next](25-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/25-03.md b/25-03.md index 52fbf01..15b6a32 100644 --- a/25-03.md +++ b/25-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](25-02.html) [Table of Contents](index.html) [Next](25-04.html) - ------------------------ --------------------------------- -------------------- - It's worth pointing out again that the bit mask operates on the data in the latches, not on the data in display memory. This makes the bit mask a flexible resource that with a little imagination can be used for some @@ -87,11 +83,3 @@ setting of 01H that produces blue leaves the green plane (plane 1) unchanged. In order to generate blue unconditionally, it would be necessary to set the Map Mask register to 0FH, clear memory, and then set the Map Mask register to 01H and fill with blue. - - ------------------------ --------------------------------- -------------------- - [Previous](25-02.html) [Table of Contents](index.html) [Next](25-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/25-04.md b/25-04.md index 19618bd..6ea0e48 100644 --- a/25-04.md +++ b/25-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](25-03.html) [Table of Contents](index.html) [Next](25-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 25.2 L25-2.ASM** ; Program to illustrate operation of Map Mask register when drawing @@ -122,11 +118,3 @@ that set/reset rather than the Map Mask register is used to control color. The preexisting pattern is completely overwritten this time, because the set/reset circuitry writes 0-bytes to planes that must be off as well as 0FFH-bytes to planes that must be on. - - ------------------------ --------------------------------- -------------------- - [Previous](25-03.html) [Table of Contents](index.html) [Next](25-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/25-05.md b/25-05.md index 325b005..908d755 100644 --- a/25-05.md +++ b/25-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](25-04.html) [Table of Contents](index.html) [Next](25-06.html) - ------------------------ --------------------------------- -------------------- - **LISTING 25.3 L25-3.ASM** ; Program to illustrate operation of set/reset circuitry to force @@ -242,11 +238,3 @@ be used to control individual pixels. start endp cseg ends end start - - ------------------------ --------------------------------- -------------------- - [Previous](25-04.html) [Table of Contents](index.html) [Next](25-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/25-06.md b/25-06.md index c36e6aa..8dd72be 100644 --- a/25-06.md +++ b/25-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](25-05.html) [Table of Contents](index.html) [Next](26-01.html) - ------------------------ --------------------------------- -------------------- - There is no clearly defined role for the set/reset circuitry, as there is for, say, the bit mask. In many cases, set/reset is largely interchangeable with CPU data, particularly with CPU data written in @@ -44,11 +40,3 @@ code in this part of the book. Using macros for word OUTs is still not a bad idea in that it does no harm, but in my opinion it's no longer necessary. Word **OUT**s are standard now, and it's been a long time since I've heard of them causing any problems. - - ------------------------ --------------------------------- -------------------- - [Previous](25-05.html) [Table of Contents](index.html) [Next](26-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/26-01.md b/26-01.md index 755d2fa..0f23c0c 100644 --- a/26-01.md +++ b/26-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](25-06.html) [Table of Contents](index.html) [Next](26-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 26\ VGA Write Mode 3 {#Heading1} ----------------- @@ -70,11 +66,3 @@ display memory only when 1 bits in the font pattern are drawn. As a result, the characters appear to be painted into the background, rather than over it. Another advantage of the code in Listing 26.1 is that the characters can be drawn in any of the 16 available colors. - - ------------------------ --------------------------------- -------------------- - [Previous](25-06.html) [Table of Contents](index.html) [Next](26-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/26-02.md b/26-02.md index 0b0f19e..1186295 100644 --- a/26-02.md +++ b/26-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](26-01.html) [Table of Contents](index.html) [Next](26-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 26.1 L26-1.ASM** ; Program to illustrate operation of write mode 3 of the VGA. @@ -297,11 +293,3 @@ ; cseg ends end start - - ------------------------ --------------------------------- -------------------- - [Previous](26-01.html) [Table of Contents](index.html) [Next](26-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/26-03.md b/26-03.md index 6327c4e..6a84a24 100644 --- a/26-03.md +++ b/26-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](26-02.html) [Table of Contents](index.html) [Next](27-01.html) - ------------------------ --------------------------------- -------------------- - The key to understanding Listing 26.1 is understanding the effect of ANDing the rotated CPU data with the contents of the Bit Mask register. The CPU data is the pattern for the character to be drawn, with bits @@ -435,11 +431,3 @@ immediate interest, and, in general, I highly recommend doing exactly that, since IBM (or clone manufacturers) may well someday use some of those reserved bits or change the meanings of some of the bits that are currently in use. - - ------------------------ --------------------------------- -------------------- - [Previous](26-02.html) [Table of Contents](index.html) [Next](27-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/27-01.md b/27-01.md index bba7c74..2a064e0 100644 --- a/27-01.md +++ b/27-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](26-03.html) [Table of Contents](index.html) [Next](27-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 27\ Yet Another VGA Write Mode {#Heading1} --------------------------- @@ -121,11 +117,3 @@ Since VGA registers are readable, the correct way to select write mode 2 on the VGA is to read the Graphics Mode register, mask off bits 1 and 0, OR in 00000010b (02H), and write the result back to the Graphics Mode register, thereby leaving the other bits in the register undisturbed. - - ------------------------ --------------------------------- -------------------- - [Previous](26-03.html) [Table of Contents](index.html) [Next](27-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/27-02.md b/27-02.md index 0186101..4ab39a5 100644 --- a/27-02.md +++ b/27-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](27-01.html) [Table of Contents](index.html) [Next](27-03.html) - ------------------------ --------------------------------- -------------------- - #### Copying Chunky Bitmaps to VGA Memory Using Write Mode 2 {#Heading5} Let's take a look at two examples of write mode 2 in action. Listing @@ -261,11 +257,3 @@ image. DrawFromChunkyBitmap endp Code ends end Start - - ------------------------ --------------------------------- -------------------- - [Previous](27-01.html) [Table of Contents](index.html) [Next](27-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/27-03.md b/27-03.md index 7fcbc21..e4048fc 100644 --- a/27-03.md +++ b/27-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](27-02.html) [Table of Contents](index.html) [Next](27-04.html) - ------------------------ --------------------------------- -------------------- - "That's an interesting application of write mode 2," you may well say, "but is it really useful?" While the ability to convert chunky bitmaps into VGA bitmaps does have its uses, Listing 27.1 is primarily intended @@ -366,11 +362,3 @@ the CPU byte in write mode 2 to select the color in which to draw. Start endp Code ends end Start - - ------------------------ --------------------------------- -------------------- - [Previous](27-02.html) [Table of Contents](index.html) [Next](27-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/27-04.md b/27-04.md index 2076ba3..4356d3c 100644 --- a/27-04.md +++ b/27-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](27-03.html) [Table of Contents](index.html) [Next](27-05.html) - ------------------------ --------------------------------- -------------------- - ### When to Use Write Mode 2 and When to Use Set/Reset {#Heading7} As indicated earlier, write mode 2 and set/reset are functionally @@ -114,11 +110,3 @@ text mode and back becomes painless. The memory used by mode 3 doesn't overlap the relocated mode 10H bitmap at all (unless additional portions of font memory are loaded), so all you need do is set bit 7 of AL on mode sets in order to flip back and forth between the two modes. - - ------------------------ --------------------------------- -------------------- - [Previous](27-03.html) [Table of Contents](index.html) [Next](27-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/27-05.md b/27-05.md index fee442e..758722c 100644 --- a/27-05.md +++ b/27-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](27-04.html) [Table of Contents](index.html) [Next](28-01.html) - ------------------------ --------------------------------- -------------------- - Another interesting point about flipping from graphics to text and back is that the standard mode 3 character/attribute map doesn't actually take up every byte of the first 4000 bytes of planes 0 and 1. The @@ -236,11 +232,3 @@ rewarding!) VGA to cover. Start endp Code ends end Start - - ------------------------ --------------------------------- -------------------- - [Previous](27-04.html) [Table of Contents](index.html) [Next](28-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/28-01.md b/28-01.md index 3a8894c..07d9230 100644 --- a/28-01.md +++ b/28-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](27-05.html) [Table of Contents](index.html) [Next](28-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 28\ Reading VGA Memory {#Heading1} ------------------- @@ -66,11 +62,3 @@ repeatedly copying the image back to system memory, again one plane at a time, clearing the old image, and copying the image to a new location in VGA memory. Note the differing settings of the Read Map and Map Mask registers. - - ------------------------ --------------------------------- -------------------- - [Previous](27-05.html) [Table of Contents](index.html) [Next](28-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/28-02.md b/28-02.md index f62b24c..ca81a63 100644 --- a/28-02.md +++ b/28-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](28-01.html) [Table of Contents](index.html) [Next](28-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 28.1 L28-1.ASM** ; Program to illustrate the use of the Read Map register in read mode 0. @@ -239,11 +235,3 @@ GetImageOffset endp code ends end Start - - ------------------------ --------------------------------- -------------------- - [Previous](28-01.html) [Table of Contents](index.html) [Next](28-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/28-03.md b/28-03.md index 9478deb..cb55564 100644 --- a/28-03.md +++ b/28-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](28-02.html) [Table of Contents](index.html) [Next](28-04.html) - ------------------------ --------------------------------- -------------------- - By the way, the code in Listing 28.1 is intended only to illustrate read mode 0, and is, in general, a poor way to perform animation, since it's slow and tends to flicker. Later in this book, we'll take a look at some @@ -49,11 +45,3 @@ obvious application is in implementing flood-fill algorithms, since read mode 1 makes it easy to tell when a given byte contains a pixel of a boundary color. Another application is in detecting on-screen object collisions, as illustrated by the code in Listing 28.2. - - ------------------------ --------------------------------- -------------------- - [Previous](28-02.html) [Table of Contents](index.html) [Next](28-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/28-04.md b/28-04.md index 3fb7e7e..4bef6d4 100644 --- a/28-04.md +++ b/28-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](28-03.html) [Table of Contents](index.html) [Next](28-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 28.2 L28-2.ASM** ; Program to illustrate use of read mode 1 (color compare mode) @@ -219,11 +215,3 @@ set to 0 (meaning all reads of VGA memory will return 0FFH). Under these circumstances, you can use a single **AND** instruction to both read and write VGA memory, since ANDing any value with 0FFH leaves that value unchanged. - - ------------------------ --------------------------------- -------------------- - [Previous](28-03.html) [Table of Contents](index.html) [Next](28-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/28-05.md b/28-05.md index d6520ed..6cee474 100644 --- a/28-05.md +++ b/28-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](28-04.html) [Table of Contents](index.html) [Next](29-01.html) - ------------------------ --------------------------------- -------------------- - Listing 28.3 illustrates an efficient use of write mode 3 in conjunction with read mode 1 and a Color Don't Care register setting of 0. The mask in AL is passed directly to the VGA's bit mask (that's how write mode 3 @@ -144,11 +140,3 @@ selection, page flipping, and Mode X. And that's not to mention actual uses to which the VGA's hardware can be put, including lines, circles, polygons, and my personal favorite, animation. We've covered a lot of challenging and rewarding ground—and we've only just begun. - - ------------------------ --------------------------------- -------------------- - [Previous](28-04.html) [Table of Contents](index.html) [Next](29-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/29-01.md b/29-01.md index 6ddb510..e670311 100644 --- a/29-01.md +++ b/29-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](28-05.html) [Table of Contents](index.html) [Next](29-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 29\ Saving Screens and Other VGA Mysteries {#Heading1} --------------------------------------- @@ -192,11 +188,3 @@ by Listing 29.1 back into the mode 10H frame buffer. Start endp Code ends end Start - - ------------------------ --------------------------------- -------------------- - [Previous](28-05.html) [Table of Contents](index.html) [Next](29-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/29-02.md b/29-02.md index 25db739..b8bb755 100644 --- a/29-02.md +++ b/29-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](29-01.html) [Table of Contents](index.html) [Next](29-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 29.2 L29-2.ASM** ; Program to restore a mode 10h EGA graphics screen from @@ -139,11 +135,3 @@ certainly won't be the desired screen image. For screen restoring, you must be in write mode 0, with the Bit Mask register set to 0FFH and Data Rotate register set to 0 (no data rotation and the logical function set to pass the data through unchanged). - - ------------------------ --------------------------------- -------------------- - [Previous](29-01.html) [Table of Contents](index.html) [Next](29-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/29-03.md b/29-03.md index 8a058ff..fe9959b 100644 --- a/29-03.md +++ b/29-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](29-02.html) [Table of Contents](index.html) [Next](29-04.html) - ------------------------ --------------------------------- -------------------- - ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ![](images/i.jpg) *While these requirements are no problem if you're simply calling a subroutine in order to save an image from your program, they pose a considerable problem if you're designing a hot-key operated TSR that can capture a screen image at any time. With the EGA specifically, there's never any way to tell what state the registers are currently in, since the registers aren't readable. (More on this issue later in this chapter.) As a result, any TSR that sets the Bit Mask to 0FFH, the Data Rotate register to 0, and so on runs the risk of interfering with the drawing code of the program that's already running.* ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ @@ -108,11 +104,3 @@ monitor is to see them, and that's just what the program in Listing ![](images/29-02.jpg)\ **Figure 29.2**  *Color translation via the palette registers.* - - ------------------------ --------------------------------- -------------------- - [Previous](29-02.html) [Table of Contents](index.html) [Next](29-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/29-04.md b/29-04.md index 2907736..d2e11df 100644 --- a/29-04.md +++ b/29-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](29-03.html) [Table of Contents](index.html) [Next](29-05.html) - ------------------------ --------------------------------- -------------------- - How does one go about setting the palette registers? Well, it's certainly possible to set the palette registers directly by addressing them at registers 0 through 0FH of the Attribute Controller. However, @@ -310,11 +306,3 @@ mapped to colors 0-3FH by the palette registers. Start endp Code ends end Start - - ------------------------ --------------------------------- -------------------- - [Previous](29-03.html) [Table of Contents](index.html) [Next](29-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/29-05.md b/29-05.md index c3f582e..e2f5f90 100644 --- a/29-05.md +++ b/29-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](29-04.html) [Table of Contents](index.html) [Next](29-06.html) - ------------------------ --------------------------------- -------------------- - ### Overscan {#Heading5} While we're at it, I'm going to touch on overscan. Overscan is the color @@ -111,11 +107,3 @@ screen blanking. Start endp Code ends end Start - - ------------------------ --------------------------------- -------------------- - [Previous](29-04.html) [Table of Contents](index.html) [Next](29-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/29-06.md b/29-06.md index 0cb2d01..ca1abd9 100644 --- a/29-06.md +++ b/29-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](29-05.html) [Table of Contents](index.html) [Next](30-01.html) - ------------------------ --------------------------------- -------------------- - Does that do it for color selection? Yes and no. For the EGA, we've covered the whole of color selection—but not so for the VGA. The VGA can emulate everything we've discussed, but actually performs one 4-bit to @@ -72,11 +68,3 @@ those legendary delays. ![](images/29-04.jpg)\ **Figure 29.4**  *Graphics mode register fields.* - - ------------------------ --------------------------------- -------------------- - [Previous](29-05.html) [Table of Contents](index.html) [Next](30-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/30-01.md b/30-01.md index 177966e..ec445a4 100644 --- a/30-01.md +++ b/30-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](29-06.html) [Table of Contents](index.html) [Next](30-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 30\ Video Est Omnis Divisa {#Heading1} ----------------------- @@ -123,11 +119,3 @@ line lower, because the split screen doesn't start until *after* the first scan line, and that produces a jittering effect as the program switches the split screen on and off. (On the EGA, the split screen may display *two* scan lines lower, for reasons I'll discuss shortly.) - - ------------------------ --------------------------------- -------------------- - [Previous](29-06.html) [Table of Contents](index.html) [Next](30-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/30-02.md b/30-02.md index 978b511..6b87148 100644 --- a/30-02.md +++ b/30-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](30-01.html) [Table of Contents](index.html) [Next](30-03.html) - ------------------------ --------------------------------- -------------------- - Finally, after another keypress, Listing 30.1 halts. **LISTING 30.1 L30-1.ASM** @@ -378,11 +374,3 @@ Finally, after another keypress, Listing 30.1 halts. ;********************************************************************* Code ends end Start - - ------------------------ --------------------------------- -------------------- - [Previous](30-01.html) [Table of Contents](index.html) [Next](30-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/30-03.md b/30-03.md index ddd3694..1046743 100644 --- a/30-03.md +++ b/30-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](30-02.html) [Table of Contents](index.html) [Next](30-04.html) - ------------------------ --------------------------------- -------------------- - #### VGA and EGA Split-Screen Operation Don't Mix {#Heading5} You must set the **IS\_VGA** equate at the start of Listing 30.1 @@ -104,11 +100,3 @@ comes to the split screen, and that's in the area of panning when the split screen is on. This isn't a bug—it's just one of the many areas in which the VGA's designers learned from the shortcomings of the EGA and went the EGA one better. - - ------------------------ --------------------------------- -------------------- - [Previous](30-02.html) [Table of Contents](index.html) [Next](30-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/30-04.md b/30-04.md index 31c58a1..c6c8f23 100644 --- a/30-04.md +++ b/30-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](30-03.html) [Table of Contents](index.html) [Next](30-05.html) - ------------------------ --------------------------------- -------------------- - ### Split Screen and Panning {#Heading8} Back in Chapter 23, I presented a program that performed smooth @@ -65,11 +61,3 @@ panning suppression in the split screen won't work in this version, however, because the EGA lacks the capability to support that feature. When the EGA version runs, the split screen simply jerks back and forth during both panning sessions. - - ------------------------ --------------------------------- -------------------- - [Previous](30-03.html) [Table of Contents](index.html) [Next](30-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/30-05.md b/30-05.md index 18c3b9b..1879362 100644 --- a/30-05.md +++ b/30-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](30-04.html) [Table of Contents](index.html) [Next](30-06.html) - ------------------------ --------------------------------- -------------------- - **LISTING 30.2 L30-2.ASM** ; Demonstrates the interaction of the split screen and @@ -422,11 +418,3 @@ ;********************************************************************* Codeends endStart - - ------------------------ --------------------------------- -------------------- - [Previous](30-04.html) [Table of Contents](index.html) [Next](30-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/30-06.md b/30-06.md index 986a45d..df6db64 100644 --- a/30-06.md +++ b/30-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](30-05.html) [Table of Contents](index.html) [Next](30-07.html) - ------------------------ --------------------------------- -------------------- - ### Notes on Setting and Reading Registers {#Heading10} There are a few interesting points regarding setting and reading @@ -79,11 +75,3 @@ disabling interrupts for much too long a time.) What if you wanted to pan faster? Well, you could of course just move two pixels at a time rather than one; I assure you no one will ever notice when you're panning at a rate of 10 or more times per second. - - ------------------------ --------------------------------- -------------------- - [Previous](30-05.html) [Table of Contents](index.html) [Next](30-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/30-07.md b/30-07.md index 37f7be2..690ed6a 100644 --- a/30-07.md +++ b/30-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](30-06.html) [Table of Contents](index.html) [Next](31-01.html) - ------------------------ --------------------------------- -------------------- - ### Split Screens in Other Modes {#Heading11} So far we've only discussed the split screen in mode 10H. What about @@ -58,11 +54,3 @@ stopping it with Ctrl-NumLock that I was able to be sure that it was, in fact, byte panning, not pel panning.) In short, use the fancy stuff—but only when you have - - ------------------------ --------------------------------- -------------------- - [Previous](30-06.html) [Table of Contents](index.html) [Next](31-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/31-01.md b/31-01.md index 6217a09..abcd8b7 100644 --- a/31-01.md +++ b/31-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](30-07.html) [Table of Contents](index.html) [Next](31-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 31\ Higher 256-Color Resolution on the VGA {#Heading1} --------------------------------------- @@ -123,11 +119,3 @@ intentionally limited the maximum size of the bitmap in mode 13H to 64K, thereby limiting resolution to 320x200. This was accomplished *in hardware*, so there is no way to extend the bitmap organization of mode 13H to 320x400 mode. - - ------------------------ --------------------------------- -------------------- - [Previous](30-07.html) [Table of Contents](index.html) [Next](31-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/31-02.md b/31-02.md index 08a065f..322e77a 100644 --- a/31-02.md +++ b/31-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](31-01.html) [Table of Contents](index.html) [Next](31-03.html) - ------------------------ --------------------------------- -------------------- - That's a shame, because mode 13H has the simplest bitmap organization of any mode—one long, linear bitmap, with each byte controlling one pixel. We can't have that organization, though, so we'll have to find an @@ -75,11 +71,3 @@ Listing 31.1 should be easily understood; a series of diagonal, horizontal, and vertical lines are drawn one pixel at a time based on a list of line descriptors, with the draw colors incremented for each successive time through the line list. - - ------------------------ --------------------------------- -------------------- - [Previous](31-01.html) [Table of Contents](index.html) [Next](31-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/31-03.md b/31-03.md index 4823477..0b73322 100644 --- a/31-03.md +++ b/31-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](31-02.html) [Table of Contents](index.html) [Next](31-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 31.1 L31-1.ASM** ; Program to demonstrate pixel drawing in 320x400 256-color @@ -331,11 +327,3 @@ Code ends ; end Start - - ------------------------ --------------------------------- -------------------- - [Previous](31-02.html) [Table of Contents](index.html) [Next](31-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/31-04.md b/31-04.md index 0772df3..6903fa5 100644 --- a/31-04.md +++ b/31-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](31-03.html) [Table of Contents](index.html) [Next](31-05.html) - ------------------------ --------------------------------- -------------------- - The interesting aspects of Listing 31.1 are three. First, the **Set320x400Mode** subroutine selects 320x400 256-color mode. This is accomplished by performing a mode 13H mode set followed by then putting @@ -106,11 +102,3 @@ speed. As I mentioned above, better speed yet could be achieved by a color-bar algorithm that draws all the pixels in plane 0, then all the pixels in plane 1, and so on, thereby avoiding the overhead of constantly reprogramming the Map Mask register. - - ------------------------ --------------------------------- -------------------- - [Previous](31-03.html) [Table of Contents](index.html) [Next](31-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/31-05.md b/31-05.md index 28bb3ab..6614e2f 100644 --- a/31-05.md +++ b/31-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](31-04.html) [Table of Contents](index.html) [Next](32-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 31.2 L31-2.ASM** ; Program to demonstrate the two pages available in 320x400 @@ -283,11 +279,3 @@ but *four* 320x200 256-color display pages, starting at offsets 0, half as many pixels per screen can as much as double drawing speeds; that's one reason that many games run at 320x200, and even then often limit the active display drawing area to only a portion of the screen. - - ------------------------ --------------------------------- -------------------- - [Previous](31-04.html) [Table of Contents](index.html) [Next](32-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/32-01.md b/32-01.md index e6c5f53..62c17ab 100644 --- a/32-01.md +++ b/32-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](31-05.html) [Table of Contents](index.html) [Next](32-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 32\ Be It Resolved: 360x480 {#Heading1} ------------------------ @@ -115,11 +111,3 @@ by all means make a short forward call to Chapter 35 and digest it. The line-draw code presented below has been altered to select 360x480 256-color mode, and to cycle through all 256 colors that this mode supports, drawing each line in a different color. - - ------------------------ --------------------------------- -------------------- - [Previous](31-05.html) [Table of Contents](index.html) [Next](32-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/32-02.md b/32-02.md index a954ccb..69aca35 100644 --- a/32-02.md +++ b/32-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](32-01.html) [Table of Contents](index.html) [Next](32-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 32.1 L32-1.ASM** ; Borland C/C++ tiny/small/medium model-callable assembler @@ -215,11 +211,3 @@ _Read360x480Dot endp _TEX Tends end - - ------------------------ --------------------------------- -------------------- - [Previous](32-01.html) [Table of Contents](index.html) [Next](32-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/32-03.md b/32-03.md index 0b5eba1..6b163b3 100644 --- a/32-03.md +++ b/32-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](32-02.html) [Table of Contents](index.html) [Next](32-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 32.2 L32-2.C** * Sample program to illustrate VGA line drawing in 360x480 @@ -212,11 +208,3 @@ most of the program is im-plemented in C. ------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ![](images/i.jpg) *Drawing in 360x480 256-color mode can sometimes actually be faster than in the 16-color modes, because the byte-per-pixel display memory organization of 256-color mode eliminates the need to read display memory before writing to it in order to isolate individual pixels coexisting within a single byte. In addition, 360x480 256-color mode is a variant of Mode X, which we'll encounter in detail in Chapter 47, and supports all the high-performance features of Mode X.* ------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - ------------------------ --------------------------------- -------------------- - [Previous](32-02.html) [Table of Contents](index.html) [Next](32-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/32-04.md b/32-04.md index 1f68ec6..e6b93e8 100644 --- a/32-04.md +++ b/32-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](32-03.html) [Table of Contents](index.html) [Next](32-05.html) - ------------------------ --------------------------------- -------------------- - The second thing you'll notice is that exquisite shading effects are possible in 360x480 256-color mode; adjacent lines blend together remarkably smoothly, even with the default palette. The VGA allows you @@ -86,11 +82,3 @@ per character. Given that graphics modes *can't* display 9 dots per character (there's only enough information for eight 16pixels or four 256-color pixels in each memory fetch, and that's that), we'd seem to be at an impasse. - - ------------------------ --------------------------------- -------------------- - [Previous](32-03.html) [Table of Contents](index.html) [Next](32-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/32-05.md b/32-05.md index 4c68e3a..f24d989 100644 --- a/32-05.md +++ b/32-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](32-04.html) [Table of Contents](index.html) [Next](33-01.html) - ------------------------ --------------------------------- -------------------- - The key to solving this problem lies in recalling that the VGA is designed to drive a monitor that sweeps the electron beam across the screen at exactly the same speed, no matter what mode the VGA is in. If @@ -101,11 +97,3 @@ EGA, and generally even VGA modes to shame. There's more and better to come, though; in later chapters, we'll return to high-resolution 256-color programming in a big way, by exploring the tremendous potential of these modes for real time 2-D and 3-D animation. - - ------------------------ --------------------------------- -------------------- - [Previous](32-04.html) [Table of Contents](index.html) [Next](33-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/33-01.md b/33-01.md index 621b079..11ae63f 100644 --- a/33-01.md +++ b/33-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](32-05.html) [Table of Contents](index.html) [Next](33-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 33\ Yogi Bear and Eurythmics Confront VGA Colors {#Heading1} --------------------------------------------- @@ -118,11 +114,3 @@ values, one each for red, green, and blue; for each color component, the higher the number, the brighter the color, with 0 turning that color off in the pixel and 63 (3FH) making that color maximum brightness. Got all that? - - ------------------------ --------------------------------- -------------------- - [Previous](32-05.html) [Table of Contents](index.html) [Next](33-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/33-02.md b/33-02.md index ee039e1..1f1d222 100644 --- a/33-02.md +++ b/33-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](33-01.html) [Table of Contents](index.html) [Next](33-03.html) - ------------------------ --------------------------------- -------------------- - #### Color Paging with the Color Select Register {#Heading6} "Wait a minute," you say bemusedly. "Aren't you missing some bits @@ -103,11 +99,3 @@ BL contains the number of the palette RAM register to set and the lower Having said that, let's leave the palette RAM behind (presumably in a pass-through state) and move on to the DAC, which is the right place to do color translation on the VGA. - - ------------------------ --------------------------------- -------------------- - [Previous](33-01.html) [Table of Contents](index.html) [Next](33-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/33-03.md b/33-03.md index bdf81b9..ffc7009 100644 --- a/33-03.md +++ b/33-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](33-02.html) [Table of Contents](index.html) [Next](33-04.html) - ------------------------ --------------------------------- -------------------- - #### Setting the DAC {#Heading9} Like the palette RAM, the DAC registers can be set either directly or @@ -128,11 +124,3 @@ gradient of each of the three primary colors and of a mix of red and blue. Run the program; I suspect you'll be surprised at the stunning display this short program produces. Clever color manipulation is perhaps the easiest way to produce truly eye-catching effects on the PC. - - ------------------------ --------------------------------- -------------------- - [Previous](33-02.html) [Table of Contents](index.html) [Next](33-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/33-04.md b/33-04.md index 9e95837..2cdbeaa 100644 --- a/33-04.md +++ b/33-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](33-03.html) [Table of Contents](index.html) [Next](34-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 33.1 L33-1.ASM** ; Program to demonstrate use of the DAC registers by selecting a @@ -204,11 +200,3 @@ In the next chapter and Chapter A on the companion CD-ROM, we'll look at some more code that plays with VGA color. We'll explore in more detail the process of reading and writing the palette RAM and DAC registers, and we'll observe color paging and cycling in action. - - ------------------------ --------------------------------- -------------------- - [Previous](33-03.html) [Table of Contents](index.html) [Next](34-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/34-01.md b/34-01.md index 240a26e..177e75b 100644 --- a/34-01.md +++ b/34-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](33-04.html) [Table of Contents](index.html) [Next](34-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 34\ Changing Colors without Writing Pixels {#Heading1} --------------------------------------- @@ -114,11 +110,3 @@ of the problem with the DAC, and shortly we'll get to a tool that will let you explore for yourself the extent of the problem on computers in which you're interested. First, though, we must address *another* DAC loading problem: the BIOS. - - ------------------------ --------------------------------- -------------------- - [Previous](33-04.html) [Table of Contents](index.html) [Next](34-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/34-02.md b/34-02.md index 4482432..36b038e 100644 --- a/34-02.md +++ b/34-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](34-01.html) [Table of Contents](index.html) [Next](34-03.html) - ------------------------ --------------------------------- -------------------- - #### Loading the DAC via the BIOS {#Heading5} The DAC can be loaded either directly or through subfunctions 10H (for a @@ -104,11 +100,3 @@ it to be otherwise. However, load the DAC any way you like; just don't blame me if you get a call from someone who's claims that your program sometimes turns their screen into something resembling month-old yogurt. It's not really your fault, of course—but try explaining that to *them!* - - ------------------------ --------------------------------- -------------------- - [Previous](34-01.html) [Table of Contents](index.html) [Next](34-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/34-03.md b/34-03.md index fe897a3..f6e643e 100644 --- a/34-03.md +++ b/34-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](34-02.html) [Table of Contents](index.html) [Next](34-04.html) - ------------------------ --------------------------------- -------------------- - ### A Test Program for Color Cycling {#Heading7} Anyway, the choice of how to load the DAC is yours. Given that I'm not @@ -273,11 +269,3 @@ in.) int 21h endstart - - ------------------------ --------------------------------- -------------------- - [Previous](34-02.html) [Table of Contents](index.html) [Next](34-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/34-04.md b/34-04.md index d8dc787..9535a1b 100644 --- a/34-04.md +++ b/34-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](34-03.html) [Table of Contents](index.html) [Next](34-05.html) - ------------------------ --------------------------------- -------------------- - The big question is, How does Listing 34.1 cycle colors? Via the BIOS or directly? With interrupts enabled or disabled? *Et cetera?* @@ -120,11 +116,3 @@ task. ------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ![](images/i.jpg) *The key to getting all the color cycling to work in the above example, however, would be to assign each color cycling task a different part of the DAC, with each part cycled independently as needed. If, as is likely, the total number of DAC locations cycled proved to be too great to manage in one frame, you could simply cycle the colors of the stars after one frame, the colors of the meteors after the next, and the colors of the jets after yet another frame, then back around to cycling the colors of the stars. By splitting up the DAC in this manner and interleaving the cycling tasks, you can perform a great deal of seemingly complex color animation without loading very much of the DAC during any one frame.* ------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - ------------------------ --------------------------------- -------------------- - [Previous](34-03.html) [Table of Contents](index.html) [Next](34-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/34-05.md b/34-05.md index 850d09f..35b28f2 100644 --- a/34-05.md +++ b/34-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](34-04.html) [Table of Contents](index.html) [Next](35-01.html) - ------------------------ --------------------------------- -------------------- - Yet another and somewhat odder workaround is that of using only 128 DAC locations and page flipping. (Page flipping in 256-color modes involves using the VGA's undocumented 256-color modes; see Chapters 31, 43, and @@ -119,11 +115,3 @@ which is to say that there's a very great deal of potential indeed. Put color cycling or color paging together with the page flipping and image drawing techniques explored elsewhere in this book, and you'll leave the audience gasping and wondering "How the heck did they *do* that?" - - ------------------------ --------------------------------- -------------------- - [Previous](34-04.html) [Table of Contents](index.html) [Next](35-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/35-01.md b/35-01.md index ac284e0..7a05163 100644 --- a/35-01.md +++ b/35-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](34-05.html) [Table of Contents](index.html) [Next](35-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 35\ Bresenham Is Fast, and Fast Is Good {#Heading1} ------------------------------------ @@ -132,11 +128,3 @@ either the horizontal or the vertical direction, or both. ![](images/35-01.jpg)\ **Figure 35.1**  *Approximating a true line from a pixel array.* - - ------------------------ --------------------------------- -------------------- - [Previous](34-05.html) [Table of Contents](index.html) [Next](35-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/35-02.md b/35-02.md index e5c8ca9..b7fb81a 100644 --- a/35-02.md +++ b/35-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](35-01.html) [Table of Contents](index.html) [Next](35-03.html) - ------------------------ --------------------------------- -------------------- - Let's examine the case of drawing a line where the horizontal, or X length of the line is greater than the vertical, or Y length, and both lengths are greater than 0. For example, suppose we are drawing a line @@ -130,11 +126,3 @@ acceptance the algorithm is certainly good enough. Then, too, users hate waiting for their computer to finish drawing. By any standard of drawing performance, Bresenham's algorithm excels. - - ------------------------ --------------------------------- -------------------- - [Previous](35-01.html) [Table of Contents](index.html) [Next](35-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/35-03.md b/35-03.md index c518097..ff1a8c7 100644 --- a/35-03.md +++ b/35-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](35-02.html) [Table of Contents](index.html) [Next](35-04.html) - ------------------------ --------------------------------- -------------------- - ### An Implementation in C {#Heading6} It's time to get down and look at some actual working code. Listing 35.1 @@ -201,11 +197,3 @@ Listing 35.2 is a sample program to demonstrate the use of **EVGALine**. outportb(GC_INDEX, BIT_MASK_INDEX); outportb(GC_DATA, 0xFF); } - - ------------------------ --------------------------------- -------------------- - [Previous](35-02.html) [Table of Contents](index.html) [Next](35-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/35-04.md b/35-04.md index 4633754..c08cf46 100644 --- a/35-04.md +++ b/35-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](35-03.html) [Table of Contents](index.html) [Next](35-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 35.2 L35-2.C** /* @@ -145,11 +141,3 @@ the running error dictates, since Y is the major axis. ![](images/35-04.jpg)\ **Figure 35.4**  *Bresenham's eight possible line orientations.* - - ------------------------ --------------------------------- -------------------- - [Previous](35-03.html) [Table of Contents](index.html) [Next](35-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/35-05.md b/35-05.md index 01c73a7..b0aa36f 100644 --- a/35-05.md +++ b/35-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](35-04.html) [Table of Contents](index.html) [Next](35-06.html) - ------------------------ --------------------------------- -------------------- - There is one line-drawing function for octants 0 and 3, **Octant0**, and one line-drawing function for octants 1 and 2, **Octant1**. A single function with **if** statements could certainly be used to handle all @@ -129,11 +125,3 @@ set up in step three above, allows only the single bit controlling the pixel to be drawn to be set to this color value. For more on the various machineries the VGA brings to bear on graphics data, look back to Chapter 25. - - ------------------------ --------------------------------- -------------------- - [Previous](35-04.html) [Table of Contents](index.html) [Next](35-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/35-06.md b/35-06.md index 076a0a2..9d66a4c 100644 --- a/35-06.md +++ b/35-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](35-05.html) [Table of Contents](index.html) [Next](35-07.html) - ------------------------ --------------------------------- -------------------- - The result of all this is simply a single pixel drawn in the color set up in **EVGALine**. **EVGADot** may seem excessively complex for a function that does nothing more that draw one pixel, but programming the @@ -74,11 +70,3 @@ the sample program in Listing 35.2 runs over three times as fast on a considerably greater yet on a local bus, or with the use of write mode 3. Link each version with Listing 35.2 and compare performance—the difference is startling. - - ------------------------ --------------------------------- -------------------- - [Previous](35-05.html) [Table of Contents](index.html) [Next](35-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/35-07.md b/35-07.md index af41e96..412a1a2 100644 --- a/35-07.md +++ b/35-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](35-06.html) [Table of Contents](index.html) [Next](36-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 35.3 L35-3.ASM** ; Fast assembler implementation of Bresenham's line-drawing algorithm @@ -403,11 +399,3 @@ our two implementations of Bresenham's algorithm graphically illustrate (pun not originally intended, but allowed to stand once recognized), truly great PC code requires both a good algorithm *and* a good assembly implementation. In Listing 35.3, we've got y-oh-my, isn't it fun? - - ------------------------ --------------------------------- -------------------- - [Previous](35-06.html) [Table of Contents](index.html) [Next](36-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/36-01.md b/36-01.md index 6237124..a0b9d9f 100644 --- a/36-01.md +++ b/36-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](35-07.html) [Table of Contents](index.html) [Next](36-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 36\ The Good, the Bad, and the Run-Sliced {#Heading1} -------------------------------------- @@ -121,11 +117,3 @@ along the major axis. ![](images/36-01.jpg)\ **Figure 36.1**  *Standard Bresenham's line drawing.* - - ------------------------ --------------------------------- -------------------- - [Previous](35-07.html) [Table of Contents](index.html) [Next](36-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/36-02.md b/36-02.md index 64dbd39..17f9b75 100644 --- a/36-02.md +++ b/36-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](36-01.html) [Table of Contents](index.html) [Next](36-03.html) - ------------------------ --------------------------------- -------------------- - The run-length slice algorithm rotates matters 90 degrees, with salubrious results. The basis of the run-length slice algorithm is stepping one pixel at a time along the minor axis (the shorter @@ -114,11 +110,3 @@ nanoseconds of overhead per pixel, exclusive of the time required to actually write the pixel to display memory. That's good. - - ------------------------ --------------------------------- -------------------- - [Previous](36-01.html) [Table of Contents](index.html) [Next](36-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/36-03.md b/36-03.md index b713ff4..9dbe39d 100644 --- a/36-03.md +++ b/36-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](36-02.html) [Table of Contents](index.html) [Next](36-04.html) - ------------------------ --------------------------------- -------------------- - ### Run-Length Slice Details {#Heading5} A couple of run-length slice implementation details yet remain. First is @@ -289,11 +285,3 @@ balanced.* WorkingScreenPtr += XAdvance; *ScreenPtr = WorkingScreenPtr; } - - ------------------------ --------------------------------- -------------------- - [Previous](36-02.html) [Table of Contents](index.html) [Next](36-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/36-04.md b/36-04.md index 7633ff0..0daae42 100644 --- a/36-04.md +++ b/36-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](36-03.html) [Table of Contents](index.html) [Next](37-01.html) - ------------------------ --------------------------------- -------------------- - Notwithstanding that it's not optimized, Listing 36.1 is reasonably fast. If you run Listing 36.2 (a sample line-drawing program that you can use to test-drive Listing 36.1), you may be as surprised as I was at @@ -85,11 +81,3 @@ surprised—in which case I suggest you *not* miss the next chapter. regs.x.ax = TEXT_MODE; int86(BIOS_VIDEO_INT, ®s, ®s); } - - ------------------------ --------------------------------- -------------------- - [Previous](36-03.html) [Table of Contents](index.html) [Next](37-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/37-01.md b/37-01.md index 5aab610..1fcfba9 100644 --- a/37-01.md +++ b/37-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](36-04.html) [Table of Contents](index.html) [Next](37-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 37\ Dead Cats and Lightning Lines {#Heading1} ------------------------------ @@ -408,11 +404,3 @@ plug-compatible with the C code from the previous chapter. ret _LineDraw endp end - - ------------------------ --------------------------------- -------------------- - [Previous](36-04.html) [Table of Contents](index.html) [Next](37-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/37-02.md b/37-02.md index 8df2003..eb86bd7 100644 --- a/37-02.md +++ b/37-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](37-01.html) [Table of Contents](index.html) [Next](38-01.html) - ------------------------ --------------------------------- -------------------- - #### How Fast Is Fast? {#Heading4} Your first question is likely to be the following: Just how fast is @@ -117,11 +113,3 @@ make that level of optimization worthwhile. If your code looks broken from a performance perspective, think before you fix it; that particular cat may be dead for a perfectly good reason. I'll say it again: *Profile before you optimize*. - - ------------------------ --------------------------------- -------------------- - [Previous](37-01.html) [Table of Contents](index.html) [Next](38-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/38-01.md b/38-01.md index 63b4461..b374a02 100644 --- a/38-01.md +++ b/38-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](37-02.html) [Table of Contents](index.html) [Next](38-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 38\ The Polygon Primeval {#Heading1} --------------------- @@ -133,11 +129,3 @@ the polygon boundaries if XOR drawing is used. Consequently, filling out to the boundary lines just won't do for drawing images composed of fitted-together polygons. And because fitting polygons together is exactly what I have in mind, we need a different approach. - - ------------------------ --------------------------------- -------------------- - [Previous](37-02.html) [Table of Contents](index.html) [Next](38-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/38-02.md b/38-02.md index 663d0dc..dc9bf6e 100644 --- a/38-02.md +++ b/38-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](38-01.html) [Table of Contents](index.html) [Next](38-03.html) - ------------------------ --------------------------------- -------------------- - #### How Do You Fit Polygons Together? {#Heading5} How, then, do you fit polygons together? *Very* carefully. First, the @@ -313,11 +309,3 @@ side. #endif *ScreenPtr = (unsigned char)Color; } - - ------------------------ --------------------------------- -------------------- - [Previous](38-01.html) [Table of Contents](index.html) [Next](38-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/38-03.md b/38-03.md index 8003567..45fac6a 100644 --- a/38-03.md +++ b/38-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](38-02.html) [Table of Contents](index.html) [Next](38-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 38.3 L38-3.C** /* Sample program to exercise the polygon-filling routines. This code @@ -131,11 +127,3 @@ int YStart; /* Y coordinate of topmost line */ struct HLine * HLinePtr; /* pointer to list of horz lines */ }; - - ------------------------ --------------------------------- -------------------- - [Previous](38-02.html) [Table of Contents](index.html) [Next](38-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/38-04.md b/38-04.md index 8c60aba..f80cc36 100644 --- a/38-04.md +++ b/38-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](38-03.html) [Table of Contents](index.html) [Next](39-01.html) - ------------------------ --------------------------------- -------------------- - Listing 38.2 isn't particularly interesting; it merely draws each horizontal line in the passed-in list in the simplest possible way, one pixel at a time. (No, that doesn't make the pixel the fundamental @@ -83,11 +79,3 @@ of filling convex polygons, and the listings given are by no means fast. In the next chapter, we'll spice things up by eliminating the floating point calculations and pixel-at-a-time drawing and tossing a little assembly language into the mix. - - ------------------------ --------------------------------- -------------------- - [Previous](38-03.html) [Table of Contents](index.html) [Next](39-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/39-01.md b/39-01.md index 3194f9c..45ad7d8 100644 --- a/39-01.md +++ b/39-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](38-04.html) [Table of Contents](index.html) [Next](39-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 39\ Fast Convex Polygons {#Heading1} --------------------- @@ -138,11 +134,3 @@ display memory—a clear case of the tail wagging the dog. This is an excellent example of why, although it is possible to use C to do virtually anything, it's sometimes much simpler just to use a little assembly code and be done with it. - - ------------------------ --------------------------------- -------------------- - [Previous](38-04.html) [Table of Contents](index.html) [Next](39-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/39-02.md b/39-02.md index e537f80..af157d5 100644 --- a/39-02.md +++ b/39-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](39-01.html) [Table of Contents](index.html) [Next](39-03.html) - ------------------------ --------------------------------- -------------------- - At any rate, Listing 39.1 for this chapter shows a version of **DrawHorizontalLineList** that uses memset to draw each scan line of the polygon in a single call. When linked to Chapter 38's test program, @@ -227,11 +223,3 @@ function returned a coordinate that was one too large. ------------------- --------------------------------------------------------------------------------------------------------- ![](images/i.jpg) *Floating point is very accurate—but it is not precise. Integer calculations, properly performed, are.* ------------------- --------------------------------------------------------------------------------------------------------- - - ------------------------ --------------------------------- -------------------- - [Previous](39-01.html) [Table of Contents](index.html) [Next](39-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/39-03.md b/39-03.md index 55ae6a4..ce9382c 100644 --- a/39-03.md +++ b/39-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](39-02.html) [Table of Contents](index.html) [Next](39-04.html) - ------------------------ --------------------------------- -------------------- - Listing 39.2 shows a C implementation of integer edge tracing. Vertical and diagonal lines, which are trivial to trace, are special-cased. Other lines are broken into two categories: Y-major (closer to vertical) and @@ -153,11 +149,3 @@ for display memory accesses to complete, with the processor forced to idle by wait states. If, instead, Listing 39.3 drew to a local buffer in system memory or to a particularly fast VGA, the assembly implementation might well display a far more substantial advantage over the C code. - - ------------------------ --------------------------------- -------------------- - [Previous](39-02.html) [Table of Contents](index.html) [Next](39-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/39-04.md b/39-04.md index 6611afa..d70ceca 100644 --- a/39-04.md +++ b/39-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](39-03.html) [Table of Contents](index.html) [Next](39-05.html) - ------------------------ --------------------------------- -------------------- - And indeed it does. When the test program is modified to draw to a local buffer, both the C and assembly language versions get 0.29 seconds faster, that being a measure of the time taken by display memory wait @@ -149,11 +145,3 @@ that the C code is also machine-independent; all adapter-specific code is isolated in **DrawHorizontalLineList**. This makes it easy to add support for other graphics systems, such as the 8514/A, the XGA, or, for that matter, a completely non-PC system. - - ------------------------ --------------------------------- -------------------- - [Previous](39-03.html) [Table of Contents](index.html) [Next](39-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/39-05.md b/39-05.md index 3f157bf..87b1078 100644 --- a/39-05.md +++ b/39-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](39-04.html) [Table of Contents](index.html) [Next](40-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 39.4 L39-4.ASM** ; Scan converts an edge from (X1,Y1) to (X2,Y2), not including the @@ -170,11 +166,3 @@ ret _ScanEdge endp end - - ------------------------ --------------------------------- -------------------- - [Previous](39-04.html) [Table of Contents](index.html) [Next](40-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/40-01.md b/40-01.md index 9ca3052..48dd843 100644 --- a/40-01.md +++ b/40-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](39-05.html) [Table of Contents](index.html) [Next](40-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 40\ Of Songs, Taxes, and the Simplicity of Complex Polygons {#Heading1} -------------------------------------------------------- @@ -113,11 +109,3 @@ line. Third, we must advance the X coordinates of active edges with the same sort of error term-based, Bresenham's-like approach we used for convex polygons, again ensuring that the AET is X-sorted after advancing the edges. - - ------------------------ --------------------------------- -------------------- - [Previous](39-05.html) [Table of Contents](index.html) [Next](40-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/40-02.md b/40-02.md index 5dcd28b..3767375 100644 --- a/40-02.md +++ b/40-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](40-01.html) [Table of Contents](index.html) [Next](40-03.html) - ------------------------ --------------------------------- -------------------- - Advancing the X coordinates is easy. For each edge, we'll store the current X coordinate and all required error term information, and we'll use that to advance the edge one scan line at a time; then, we'll resort @@ -340,11 +336,3 @@ more sane and sensible corners of the universe. CurrentEdge = CurrentEdge->NextEdge; } } - - ------------------------ --------------------------------- -------------------- - [Previous](40-01.html) [Table of Contents](index.html) [Next](40-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/40-03.md b/40-03.md index 603ff6f..acaca54 100644 --- a/40-03.md +++ b/40-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](40-02.html) [Table of Contents](index.html) [Next](40-04.html) - ------------------------ --------------------------------- -------------------- - ### Complex Polygon Filling: An Implementation {#Heading5} Listing 40.1 just shown presents a function, **FillPolygon()**, that @@ -177,11 +173,3 @@ various sorts. regset.x.ax = 0x0003; int86(0x10, ®set, ®set); } - - ------------------------ --------------------------------- -------------------- - [Previous](40-02.html) [Table of Contents](index.html) [Next](40-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/40-04.md b/40-04.md index a2642c7..cd0e456 100644 --- a/40-04.md +++ b/40-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](40-03.html) [Table of Contents](index.html) [Next](40-05.html) - ------------------------ --------------------------------- -------------------- - Listing 40.4 illustrates several interesting aspects of polygon filling. The first and third polygons drawn illustrate the operation of the odd/even fill rule. The second polygon drawn illustrates how holes can @@ -116,11 +112,3 @@ scan line to the next, that's generally the case with the AET. An insertion sort might be somewhat faster, depending on the state of the AET when any particular sort occurs, but a bubble sort will generally do just fine. - - ------------------------ --------------------------------- -------------------- - [Previous](40-03.html) [Table of Contents](index.html) [Next](40-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/40-05.md b/40-05.md index e5c441f..6795e48 100644 --- a/40-05.md +++ b/40-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](40-04.html) [Table of Contents](index.html) [Next](41-01.html) - ------------------------ --------------------------------- -------------------- - An insertion sort that scans backward through the AET from the current edge rather than forward from the start of the AET could be quite a bit faster, because edges rarely move more than one or two positions through @@ -94,11 +90,3 @@ across hot coals in this book or elsewhere when there's an easier way to go, please, let me know! Thanks, Anton. - - ------------------------ --------------------------------- -------------------- - [Previous](40-04.html) [Table of Contents](index.html) [Next](41-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/41-01.md b/41-01.md index dc5eb73..b97d175 100644 --- a/41-01.md +++ b/41-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](40-05.html) [Table of Contents](index.html) [Next](41-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 41\ Those Way-Down Polygon Nomenclature Blues {#Heading1} ------------------------------------------ @@ -131,11 +127,3 @@ test whether a polygon is appropriately monotone. } while (i++ < (Length-1)); return(1); /* it's a vertical-monotone polygon */ } - - ------------------------ --------------------------------- -------------------- - [Previous](40-05.html) [Table of Contents](index.html) [Next](41-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/41-02.md b/41-02.md index c1473ee..1def0ad 100644 --- a/41-02.md +++ b/41-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](41-01.html) [Table of Contents](index.html) [Next](41-03.html) - ------------------------ --------------------------------- -------------------- - Listings 41.2 and 41.3 are variants of the fast convex polygon fill code from Chapter 39, modified to be able to handle all monotone-vertical polygons, including nonsimple ones; the edge-scanning code (Listing 39.4 @@ -130,11 +126,3 @@ from Chapter 39) remains the same, and so is not shown again here. free(WorkingHLineList.HLinePtr); return(1); } - - ------------------------ --------------------------------- -------------------- - [Previous](41-01.html) [Table of Contents](index.html) [Next](41-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/41-03.md b/41-03.md index b256de4..7ca7099 100644 --- a/41-03.md +++ b/41-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](41-02.html) [Table of Contents](index.html) [Next](41-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 41.3 L41-3.ASM** ; Draws all pixels in list of horizontal lines passed in, in mode 13h, VGA's @@ -102,11 +98,3 @@ whenever possible; that's what Listing 41.4 is. Note well that Listing 40.5 from Chapter 40 is also required in order for this code to link. Listing 41.5 is an appropriately updated version of the POLYGON.H header file. - - ------------------------ --------------------------------- -------------------- - [Previous](41-02.html) [Table of Contents](index.html) [Next](41-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/41-04.md b/41-04.md index 94c196a..207d79c 100644 --- a/41-04.md +++ b/41-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](41-03.html) [Table of Contents](index.html) [Next](42-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 41.4 L41-4.C** /* Color-fills an arbitrarily-shaped polygon described by VertexList. @@ -340,11 +336,3 @@ status is simpler and faster than my original, nonfunctional test for convexity. See what accurate terminology and effective communication can do? - - ------------------------ --------------------------------- -------------------- - [Previous](41-03.html) [Table of Contents](index.html) [Next](42-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/42-01.md b/42-01.md index 11175d0..ec2e04d 100644 --- a/42-01.md +++ b/42-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](41-04.html) [Table of Contents](index.html) [Next](42-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 42\ Wu'ed in Haste; Fried, Stewed at Leisure {#Heading1} ----------------------------------------- @@ -121,11 +117,3 @@ percent of the maximum memory bandwidth—half the fastest theoretically possible drawing speed—of an AT-bus VGA. In short, Wu antialiasing is about as fast an antialiased line approach as you could ever hope to find for the VGA. - - ------------------------ --------------------------------- -------------------- - [Previous](41-04.html) [Table of Contents](index.html) [Next](42-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/42-02.md b/42-02.md index 44462b3..eacc892 100644 --- a/42-02.md +++ b/42-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](42-01.html) [Table of Contents](index.html) [Next](42-03.html) - ------------------------ --------------------------------- -------------------- - ### Tracing and Intensity in One {#Heading4} Horizontal, vertical, and diagonal lines do not require Wu antialiasing @@ -203,11 +199,3 @@ loop unrolling. Make no mistake about it, Wu antialiasing is fast. and so needs no weighting */ DrawPixel(X1, Y1, BaseColor); } - - ------------------------ --------------------------------- -------------------- - [Previous](42-01.html) [Table of Contents](index.html) [Next](42-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/42-03.md b/42-03.md index fdd490f..10c89d7 100644 --- a/42-03.md +++ b/42-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](42-02.html) [Table of Contents](index.html) [Next](42-04.html) - ------------------------ --------------------------------- -------------------- - ### Sample Wu Antialiasing {#Heading5} The true test of any antialiasing technique is how good it looks, so @@ -173,11 +169,3 @@ both Wu-antialiased and non-antialiased lines. regset.x.ax = 0x0013; int86(0x10, ®set, ®set); } - - ------------------------ --------------------------------- -------------------- - [Previous](42-02.html) [Table of Contents](index.html) [Next](42-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/42-04.md b/42-04.md index effac8e..ec5062f 100644 --- a/42-04.md +++ b/42-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](42-03.html) [Table of Contents](index.html) [Next](42-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 42.4 L42-4.C** /* Function to draw a non-antialiased line from (X0,Y0) to (X1,Y1), using a @@ -145,11 +141,3 @@ in Listing 42.6. High-speed graphics code and fast VGAs go together like peanut butter and jelly, which is to say very well indeed; the assembly implementation ran more than twice as fast as the C code on my 486. Enough said! - - ------------------------ --------------------------------- -------------------- - [Previous](42-03.html) [Table of Contents](index.html) [Next](42-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/42-05.md b/42-05.md index 73a9201..09ac156 100644 --- a/42-05.md +++ b/42-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](42-04.html) [Table of Contents](index.html) [Next](43-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 42.6 L42-6.ASM** ; C near-callable function to draw an antialiased line from @@ -315,11 +311,3 @@ error in half, as well. With or without symmetrical processing, Wu antialiasing beats fried, stewed chicken hands-down. Trust me on this one. - - ------------------------ --------------------------------- -------------------- - [Previous](42-04.html) [Table of Contents](index.html) [Next](43-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/43-01.md b/43-01.md index ee68926..59bcee6 100644 --- a/43-01.md +++ b/43-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](42-05.html) [Table of Contents](index.html) [Next](43-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 43\ Bit-Plane Animation {#Heading1} -------------------- @@ -136,11 +132,3 @@ You bet. ![](images/43-03.jpg)\ **Figure 43.3**  *The problem of overlapping colors.* - - ------------------------ --------------------------------- -------------------- - [Previous](42-05.html) [Table of Contents](index.html) [Next](43-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/43-02.md b/43-02.md index 21e4770..f6a6841 100644 --- a/43-02.md +++ b/43-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](43-01.html) [Table of Contents](index.html) [Next](43-03.html) - ------------------------ --------------------------------- -------------------- - #### Stacking the Palette Registers {#Heading4} Suppose that instead of viewing the four bits per pixel coming out of @@ -177,11 +173,3 @@ Listing 43.1 animates 13 rather large images (each 32 pixels on a side) over a complex background at a good clip *even on a primordial 8088-based PC*. Five of the images move very quickly, while the other 8 bounce back and forth at a steady pace. - - ------------------------ --------------------------------- -------------------- - [Previous](43-01.html) [Table of Contents](index.html) [Next](43-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/43-03.md b/43-03.md index 2963328..1c76ae0 100644 --- a/43-03.md +++ b/43-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](43-02.html) [Table of Contents](index.html) [Next](43-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 43.1 L43-1.ASM** ; Program to demonstrate bit-plane animation. Performs @@ -499,11 +495,3 @@ ; Code ends end Start - - ------------------------ --------------------------------- -------------------- - [Previous](43-02.html) [Table of Contents](index.html) [Next](43-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/43-04.md b/43-04.md index 0e16fa9..388405a 100644 --- a/43-04.md +++ b/43-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](43-03.html) [Table of Contents](index.html) [Next](43-05.html) - ------------------------ --------------------------------- -------------------- - For those of you who haven't experienced the frustrations of animation programming on a PC, there's a *whole* lot of animation going on in Listing 43.1. What's more, the animation is virtually flicker-free, @@ -100,11 +96,3 @@ might be a good tradeoff for being able to draw multi-colored images as a backdrop to the high-precedence images. For the right application, high-speed flicker-free plane 3 images moving in front of an 8-color backdrop could be a potent combination indeed. - - ------------------------ --------------------------------- -------------------- - [Previous](43-03.html) [Table of Contents](index.html) [Next](43-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/43-05.md b/43-05.md index 88b2d14..02d3fd6 100644 --- a/43-05.md +++ b/43-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](43-04.html) [Table of Contents](index.html) [Next](43-06.html) - ------------------------ --------------------------------- -------------------- - Another limitation of bit-plane animation is that it's best if images stored in the same plane never cross each other. Why? Because when images do cross, the blank fringe @@ -126,11 +122,3 @@ display memory that have been already been changed, pass the point in the image that the CPU is currently drawing, and start scanning out bytes that haven't yet been changed. The result: Mismatched upper and lower portions of the image. - - ------------------------ --------------------------------- -------------------- - [Previous](43-04.html) [Table of Contents](index.html) [Next](43-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/43-06.md b/43-06.md index 23a1c53..ee0ae66 100644 --- a/43-06.md +++ b/43-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](43-05.html) [Table of Contents](index.html) [Next](44-01.html) - ------------------------ --------------------------------- -------------------- - If the CRT controller scans more slowly than the CPU can modify memory (likely with a 386, a fast VGA, and narrow images), then the CPU can rip right past the CRT controller, with the same net result of mismatched @@ -66,11 +62,3 @@ exclusive-ORing, pixel panning, or any of the many other animation techniques you have available. One or more tricks from that grab-bag should give you what you need, though, and the bigger your grab-bag, the better your programs. - - ------------------------ --------------------------------- -------------------- - [Previous](43-05.html) [Table of Contents](index.html) [Next](44-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/44-01.md b/44-01.md index e291e51..4a32cab 100644 --- a/44-01.md +++ b/44-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](43-06.html) [Table of Contents](index.html) [Next](44-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 44\ Split Screens Save the Page Flipped Day {#Heading1} ---------------------------------------- @@ -71,11 +67,3 @@ animation knowledge for for me to discuss it all in exhaustive detail I'll cover the major elements, leaving it to you to explore the finer points—and, hope, to experiment with and expand on the code I'll provide. - - ------------------------ --------------------------------- -------------------- - [Previous](43-06.html) [Table of Contents](index.html) [Next](44-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/44-02.md b/44-02.md index 73b409f..cab802d 100644 --- a/44-02.md +++ b/44-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](44-01.html) [Table of Contents](index.html) [Next](44-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 44.1 L44-1.C** /* Split screen VGA animation program. Performs page flipping in the @@ -291,11 +287,3 @@ Bouncer->LeftX = NewLeftX; /* set the final new coordinates */ Bouncer->TopY = NewTopY; } - - ------------------------ --------------------------------- -------------------- - [Previous](44-01.html) [Table of Contents](index.html) [Next](44-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/44-03.md b/44-03.md index 0ed7cb5..6587a26 100644 --- a/44-03.md +++ b/44-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](44-02.html) [Table of Contents](index.html) [Next](44-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 44.2 L44-2.ASM** ; Low-level animation routines. @@ -326,11 +322,3 @@ ret -SetBIOS8x8Font endp end - - ------------------------ --------------------------------- -------------------- - [Previous](44-02.html) [Table of Contents](index.html) [Next](44-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/44-04.md b/44-04.md index 6eae941..81c5d09 100644 --- a/44-04.md +++ b/44-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](44-03.html) [Table of Contents](index.html) [Next](44-05.html) - ------------------------ --------------------------------- -------------------- - Listing 44.1 is written in C. It could equally well have been written in assembly language, and would then have been somewhat faster. However, wanted to make the point (as I've made again and again) that assembly @@ -125,11 +121,3 @@ coordinates that are multiples of 8); this means that the character bytes in the font are automatically aligned with display memory, and no rotation or clipping of characters is needed. Finally, we'll draw all text in white. - - ------------------------ --------------------------------- -------------------- - [Previous](44-03.html) [Table of Contents](index.html) [Next](44-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/44-05.md b/44-05.md index d30942c..fffe8a6 100644 --- a/44-05.md +++ b/44-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](44-04.html) [Table of Contents](index.html) [Next](44-06.html) - ------------------------ --------------------------------- -------------------- - Given the above assumptions, drawing text is easy; we simply copy each byte of each character to the appropriate location in display memory, and *voila*, we're done. Text copying is done in write mode 0, in which @@ -67,11 +63,3 @@ so on *ad infinitum.* ![](images/44-01.jpg)\ **Figure 44.1**  *Memory allocation for mode 10h page flipping.* - - ------------------------ --------------------------------- -------------------- - [Previous](44-04.html) [Table of Contents](index.html) [Next](44-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/44-06.md b/44-06.md index c26c994..e080fcd 100644 --- a/44-06.md +++ b/44-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](44-05.html) [Table of Contents](index.html) [Next](45-01.html) - ------------------------ --------------------------------- -------------------- - #### Knowing When to Flip {#Heading8 align="center"} There's a hitch, though, and that hitch is knowing exactly when it is @@ -126,11 +122,3 @@ little quiet space to display scores, coordinates, file names, or (if all else fails) company logos. If you don't tell the user he's/she's only getting 339 scan lines of animation, he'll/she'll probably never know. - - ------------------------ --------------------------------- -------------------- - [Previous](44-05.html) [Table of Contents](index.html) [Next](45-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/45-01.md b/45-01.md index 45a022c..f2dcaa7 100644 --- a/45-01.md +++ b/45-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](44-06.html) [Table of Contents](index.html) [Next](45-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 45\ Dog Hair and Dirty Rectangles {#Heading1} ------------------------------ @@ -110,11 +106,3 @@ system memory takes exactly one cycle on the 486. In short, **OUT**s to VGAs are as much as 100 times slower than normal memory accesses, and are generally two to four times slower than even display memory accesses, although there are exceptions. - - ------------------------ --------------------------------- -------------------- - [Previous](44-06.html) [Table of Contents](index.html) [Next](45-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/45-02.md b/45-02.md index 8855e03..4352c17 100644 --- a/45-02.md +++ b/45-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](45-01.html) [Table of Contents](index.html) [Next](45-03.html) - ------------------------ --------------------------------- -------------------- - Of course, VGA display memory has its own performance problems. The fastest ISA bus VGA can, at best, support sustained write times of about 10 cycles per word-sized write on a 486/33; 15 or 20 cycles is more @@ -163,11 +159,3 @@ hardware.) Also, read/modify/write operations are performed in fast system memory rather than slow display memory, so display memory rarely needs to be read. This is particularly good because display memory is generally even slower for reads than for writes. - - ------------------------ --------------------------------- -------------------- - [Previous](45-01.html) [Table of Contents](index.html) [Next](45-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/45-03.md b/45-03.md index 3d04783..240e112 100644 --- a/45-03.md +++ b/45-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](45-02.html) [Table of Contents](index.html) [Next](45-04.html) - ------------------------ --------------------------------- -------------------- - Also, page flipping wastes a good deal of time waiting for the page to flip at the end of the frame. Dirty-rectangle animation never needs to wait for anything because partially drawn images are never present in @@ -295,11 +291,3 @@ on my 486/33, 10 11x11 images animate at a very respectable clip. } } } - - ------------------------ --------------------------------- -------------------- - [Previous](45-02.html) [Table of Contents](index.html) [Next](45-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/45-04.md b/45-04.md index bb7964c..18b2b33 100644 --- a/45-04.md +++ b/45-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](45-03.html) [Table of Contents](index.html) [Next](45-05.html) - ------------------------ --------------------------------- -------------------- - One point I'd like to make is that although the system-memory buffer in Listing 45.1 has exactly the same dimensions as the screen bitmap, that's not a requirement, and there are some good reasons not to make @@ -113,11 +109,3 @@ Listing 45.2, which provides mode set code for 640x400 mode. outpw(0x3D4, 0xB916); /* adjust the Vertical Blank End register for 400 scan lines */ } - - ------------------------ --------------------------------- -------------------- - [Previous](45-03.html) [Table of Contents](index.html) [Next](45-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/45-05.md b/45-05.md index 130e517..b52c791 100644 --- a/45-05.md +++ b/45-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](45-04.html) [Table of Contents](index.html) [Next](45-06.html) - ------------------------ --------------------------------- -------------------- - In 640x400, 16-color mode, page 0 runs from offset 0 to offset 31,999 (7CFFH), and page 1 runs from offset 32,000 (7D00H) to 63,999 (0F9FFH). Page 1 is selected by programming the Start Address registers (CRTC @@ -125,11 +121,3 @@ calls down the road. int86(0x10, ®s, ®s); /* invoke the BIOS video interrupt to set up the text */ } - - ------------------------ --------------------------------- -------------------- - [Previous](45-04.html) [Table of Contents](index.html) [Next](45-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/45-06.md b/45-06.md index 9e99822..492924f 100644 --- a/45-06.md +++ b/45-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](45-05.html) [Table of Contents](index.html) [Next](46-01.html) - ------------------------ --------------------------------- -------------------- - The 640x400 mode I've described here isn't exactly earthshaking, but it can come in handy for page flipping and CGA emulation, and I'm sure that some of you will find it useful at one time or another. @@ -120,11 +116,3 @@ In the next chapter, I'll return to the original dirty-rectangle algorithm presented in this chapter, and goose it a little with some assembly, so that we can see what dirty-rectangle animation is really made of. (Probably not dog hair....) - - ------------------------ --------------------------------- -------------------- - [Previous](45-05.html) [Table of Contents](index.html) [Next](46-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/46-01.md b/46-01.md index 152263b..09d9364 100644 --- a/46-01.md +++ b/46-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](45-06.html) [Table of Contents](index.html) [Next](46-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 46\ Who Was that Masked Image? {#Heading1} --------------------------- @@ -87,11 +83,3 @@ presented in the last chapter), and the images are now two pixels wider. That level of performance is all the more impressive considering that for this chapter I've converted the code from using rectangular images to using masked images. - - ------------------------ --------------------------------- -------------------- - [Previous](45-06.html) [Table of Contents](index.html) [Next](46-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/46-02.md b/46-02.md index 308336a..b952144 100644 --- a/46-02.md +++ b/46-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](46-01.html) [Table of Contents](index.html) [Next](46-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 46.1 L46-1.C** /* Sample simple dirty-rectangle animation program, partially optimized and @@ -520,11 +516,3 @@ ret -CopyRect endp end - - ------------------------ --------------------------------- -------------------- - [Previous](46-01.html) [Table of Contents](index.html) [Next](46-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/46-03.md b/46-03.md index 36055b4..178a2dd 100644 --- a/46-03.md +++ b/46-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](46-02.html) [Table of Contents](index.html) [Next](47-01.html) - ------------------------ --------------------------------- -------------------- - #### Masked Images {#Heading4} Masked images are rendered by drawing an object's pixels through a mask; @@ -132,11 +128,3 @@ right pixels, one after another. Animation is the art of drawing *the right pixels at the right times* so that the eye and brain see what you want them to see. Animation is a lot more challenging than merely cranking out pixels, and it sure as heck isn't a purely linear process. - - ------------------------ --------------------------------- -------------------- - [Previous](46-02.html) [Table of Contents](index.html) [Next](47-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/47-01.md b/47-01.md index db013ae..d15c7af 100644 --- a/47-01.md +++ b/47-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](46-03.html) [Table of Contents](index.html) [Next](47-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 47\ Mode X: 256-Color VGA Magic {#Heading1} ---------------------------- @@ -122,11 +118,3 @@ columns has been published about it, although John Bridges has widely distributed his code for a number of undocumented 256-color resolutions, and I'd like to acknowledge the influence of his code on the mode set routine presented in this chapter. - - ------------------------ --------------------------------- -------------------- - [Previous](46-03.html) [Table of Contents](index.html) [Next](47-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/47-02.md b/47-02.md index e8602aa..7b7a499 100644 --- a/47-02.md +++ b/47-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](47-01.html) [Table of Contents](index.html) [Next](47-03.html) - ------------------------ --------------------------------- -------------------- - Given the tremendous advantages of Mode X over the documented mode 13H, I'd very much like to get it into the hands of as many developers as possible, so I'm going to spend the next few chapters exploring this odd @@ -150,11 +146,3 @@ pay for the unfettered creativity and vast choice of the PC market. ret _Set320x240Mode endp end - - ------------------------ --------------------------------- -------------------- - [Previous](47-01.html) [Table of Contents](index.html) [Next](47-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/47-03.md b/47-03.md index a9e9ebe..06408a5 100644 --- a/47-03.md +++ b/47-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](47-02.html) [Table of Contents](index.html) [Next](47-04.html) - ------------------------ --------------------------------- -------------------- - After setting up mode 13H, Listing 47.1 alters the vertical counts and timings to select 480 visible scan lines. (There's no need to alter any horizontal values, because mode 13H and Mode X both have 320-pixel @@ -157,11 +153,3 @@ are fills, copies, and bitblts, and it's there that Mode X shines. ret _ReadPixelX endp end - - ------------------------ --------------------------------- -------------------- - [Previous](47-02.html) [Table of Contents](index.html) [Next](47-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/47-04.md b/47-04.md index 3358abe..47266fc 100644 --- a/47-04.md +++ b/47-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](47-03.html) [Table of Contents](index.html) [Next](47-05.html) - ------------------------ --------------------------------- -------------------- - ### Designing from a Mode X Perspective {#Heading5} Listing 47.4 shows Mode X rectangle fill code. The plane is selected for @@ -128,11 +124,3 @@ Listing 47.5 is 2.5 times faster than Listing 47.4 at clearing the screen on a 20-MHz cached 386 with a Paradise VGA. Although Listing 47.5 is slightly slower than an equivalent mode 13H fill routine would be, it's not grievously so. - - ------------------------ --------------------------------- -------------------- - [Previous](47-03.html) [Table of Contents](index.html) [Next](47-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/47-05.md b/47-05.md index 7914dca..ec97e5c 100644 --- a/47-05.md +++ b/47-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](47-04.html) [Table of Contents](index.html) [Next](47-06.html) - ------------------------ --------------------------------- -------------------- - ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ![](images/i.jpg) *In general, performing plane-at-a-time operations can make almost any Mode X operation, at the worst, nearly as fast as the same operation in mode 13H (although this sort of Mode X programming is admittedly fairly complex). In this pursuit, it can help to organize data structures with Mode X in mind. For example, icons could be prearranged in system memory with the pixels organized into four plane-oriented sets (or, again, in four sets per scan line to avoid a fading-in effect) to facilitate copying to the screen a plane at a time with **REP MOVS*** ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ @@ -135,11 +131,3 @@ ret _FillRectangleX endp end - - ------------------------ --------------------------------- -------------------- - [Previous](47-04.html) [Table of Contents](index.html) [Next](47-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/47-06.md b/47-06.md index 120ea63..6c79d86 100644 --- a/47-06.md +++ b/47-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](47-05.html) [Table of Contents](index.html) [Next](47-07.html) - ------------------------ --------------------------------- -------------------- - ### Hardware Assist from an Unexpected Quarter {#Heading6} Listing 47.5 illustrates the benefits of designing code from a Mode X @@ -59,11 +55,3 @@ Note that the return from Mode X's parallelism is not always 4x; some adapters lack the underlying memory bandwidth to write data that fast. However, Mode X parallel access should always be faster than mode 13H access; the only question on any given adapter is how *much* faster. - - ------------------------ --------------------------------- -------------------- - [Previous](47-05.html) [Table of Contents](index.html) [Next](47-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/47-07.md b/47-07.md index 79d28ca..5ef8e74 100644 --- a/47-07.md +++ b/47-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](47-06.html) [Table of Contents](index.html) [Next](48-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 47.6 L47-6.ASM** ; Mode X (320x240, 256 colors) rectangle fill routine. Works on all @@ -153,11 +149,3 @@ copies, blits, and pattern fills. regset.x.ax = 0x0003; /* switch back to text mode and done */ int86(0x10, ®set, ®set); } - - ------------------------ --------------------------------- -------------------- - [Previous](47-06.html) [Table of Contents](index.html) [Next](48-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/48-01.md b/48-01.md index 307cc0e..993103c 100644 --- a/48-01.md +++ b/48-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](47-07.html) [Table of Contents](index.html) [Next](48-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 48\ Mode X Marks the Latch {#Heading1} ----------------------- @@ -118,11 +114,3 @@ previous chapter's listings.) regset.x.ax = 0x0003; /* switch back to text mode and done */ int86(0x10, ®set, ®set); } - - ------------------------ --------------------------------- -------------------- - [Previous](47-07.html) [Table of Contents](index.html) [Next](48-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/48-02.md b/48-02.md index 4f19c22..a6b6516 100644 --- a/48-02.md +++ b/48-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](48-01.html) [Table of Contents](index.html) [Next](48-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 48.2 L48-2.ASM** ; Mode X (320x240, 256 colors) rectangle 4x4 pattern fill routine. @@ -179,11 +175,3 @@ ret _FillPatternX endp end - - ------------------------ --------------------------------- -------------------- - [Previous](48-01.html) [Table of Contents](index.html) [Next](48-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/48-03.md b/48-03.md index 63ba584..676e127 100644 --- a/48-03.md +++ b/48-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](48-02.html) [Table of Contents](index.html) [Next](48-04.html) - ------------------------ --------------------------------- -------------------- - Four-pixel-wide patterns are more useful than you might imagine. There are actually 2128 possible patterns (16 pixels, each with 28 possible colors); that set is certainly large enough for most color-dithering @@ -79,11 +75,3 @@ pixels in that plane, repeating for all four planes.) ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ![](images/i.jpg) *Although copying through the latches is, in general, a speedy technique, especially on slower VGAs, it's not always a win. Reading video memory tends to be quite a bit slower than writing, and on a fast VLB or PCI adapter, it can be faster to copy from main memory to display memory than it is to copy from display memory to display memory via the latches.* ------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - - ------------------------ --------------------------------- -------------------- - [Previous](48-02.html) [Table of Contents](index.html) [Next](48-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/48-04.md b/48-04.md index bbad7d4..35ed3e0 100644 --- a/48-04.md +++ b/48-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](48-03.html) [Table of Contents](index.html) [Next](48-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 48.3 L48-3.ASM** ; Mode X (320x240, 256 colors) display memory to display memory copy @@ -177,11 +173,3 @@ ret _CopyScreenToScreenX endp end - - ------------------------ --------------------------------- -------------------- - [Previous](48-03.html) [Table of Contents](index.html) [Next](48-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/48-05.md b/48-05.md index 7d346b7..4ad6735 100644 --- a/48-05.md +++ b/48-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](48-04.html) [Table of Contents](index.html) [Next](49-01.html) - ------------------------ --------------------------------- -------------------- - Listing 48.3 has an important limitation: It does not guarantee proper handling when the source and destination overlap, as in the case of a downward scroll, for example. Listing 48.3 performs top-to-bottom, @@ -187,11 +183,3 @@ matters. When you're a buyer, results are everything. All important. *Sine qua non.* The whole enchilada. If you catch my drift. - - ------------------------ --------------------------------- -------------------- - [Previous](48-04.html) [Table of Contents](index.html) [Next](49-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/49-01.md b/49-01.md index 7ae0a53..a6aebd6 100644 --- a/49-01.md +++ b/49-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](48-05.html) [Table of Contents](index.html) [Next](49-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 49\ Mode X 256-Color Animation {#Heading1} --------------------------- @@ -202,11 +198,3 @@ and that's to use the VGA's hardware. ret _CopySystemToScreenMaskedX endp end - - ------------------------ --------------------------------- -------------------- - [Previous](48-05.html) [Table of Contents](index.html) [Next](49-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/49-02.md b/49-02.md index 174e3f3..3ad15c9 100644 --- a/49-02.md +++ b/49-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](49-01.html) [Table of Contents](index.html) [Next](49-03.html) - ------------------------ --------------------------------- -------------------- - #### Faster Masked Copying {#Heading4} In the previous chapter we saw how the VGA's latches can be used to copy @@ -197,11 +193,3 @@ alignment. ret _CopyScreenToScreenMaskedX endp end - - ------------------------ --------------------------------- -------------------- - [Previous](49-01.html) [Table of Contents](index.html) [Next](49-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/49-03.md b/49-03.md index d95e20d..ec885e3 100644 --- a/49-03.md +++ b/49-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](49-02.html) [Table of Contents](index.html) [Next](49-04.html) - ------------------------ --------------------------------- -------------------- - It would be handy to have a function that, given a base image and mask, generates the four image and mask alignments and fills in the **MaskedImage** structure. Listing 49.3, together with the include file @@ -124,11 +120,3 @@ used separate parameters for simplicity and flexibility. ------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ![](images/i.jpg) *Be aware that as nifty as Mode X hardware-assisted masked copying is, whether or not it's actually faster than software-only masked or transparent copying depends upon the processor and the video adapter. The advantage of Mode X masked copying is the 32-bit parallelism; the disadvantages are the need to read display memory and the need to perform an **OUT** for every four pixels. (**OUT** is a slow 486/Pentium instruction, and most VGAs respond to **OUT**s much more slowly than to display memory writes.)* ------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - ------------------------ --------------------------------- -------------------- - [Previous](49-02.html) [Table of Contents](index.html) [Next](49-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/49-04.md b/49-04.md index aea63f7..feffe53 100644 --- a/49-04.md +++ b/49-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](49-03.html) [Table of Contents](index.html) [Next](49-05.html) - ------------------------ --------------------------------- -------------------- - ### Animation {#Heading6} Gosh. There's just no way I can discuss high-level animation @@ -284,11 +280,3 @@ the resulting image—add the animation in your imagination. ObjectToMove->X = X; /* set new location */ ObjectToMove->Y = Y; } - - ------------------------ --------------------------------- -------------------- - [Previous](49-03.html) [Table of Contents](index.html) [Next](49-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/49-05.md b/49-05.md index 01fcc59..307b03e 100644 --- a/49-05.md +++ b/49-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](49-04.html) [Table of Contents](index.html) [Next](50-01.html) - ------------------------ --------------------------------- -------------------- - Here's something worth noting: The animation is extremely smooth on a 20 MHz 386. It is somewhat more jerky on an 8 MHz 286, because only 30 frames a second can be processed. If animation looks jerky on your PC, @@ -86,11 +82,3 @@ the built-in AND, OR, and XOR functions, are available in Mode X, just as they are in the standard VGA modes. If you understand the VGA's hardware in mode 12H, try applying that knowledge to Mode X; you might be surprised at what you find you can do. - - ------------------------ --------------------------------- -------------------- - [Previous](49-04.html) [Table of Contents](index.html) [Next](50-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/50-01.md b/50-01.md index ff96d37..c96aff1 100644 --- a/50-01.md +++ b/50-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](49-05.html) [Table of Contents](index.html) [Next](50-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 50\ Adding a Dimension {#Heading1} ------------------- @@ -133,11 +129,3 @@ 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. - - ------------------------ --------------------------------- -------------------- - [Previous](49-05.html) [Table of Contents](index.html) [Next](50-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/50-02.md b/50-02.md index e933def..53f189e 100644 --- a/50-02.md +++ b/50-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](50-01.html) [Table of Contents](index.html) [Next](50-03.html) - ------------------------ --------------------------------- -------------------- - One note: I'll use a purely *right-handed* convention for coordinate systems. Right-handed means that if you hold your right hand with your fingers curled and the thumb sticking out, the thumb points along the Z @@ -127,11 +123,3 @@ clipped before it was scanned into a line list, avoiding potentially wasted scanning and eliminating the line-by-line X clipping—but it's much simpler, and, as we shall see, polygon filling performance is the least of our worries at the moment. - - ------------------------ --------------------------------- -------------------- - [Previous](50-01.html) [Table of Contents](index.html) [Next](50-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/50-03.md b/50-03.md index 3d56987..6dda3ef 100644 --- a/50-03.md +++ b/50-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](50-02.html) [Table of Contents](index.html) [Next](50-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 50.1 L50-1.ASM** ; Draws all pixels in the list of horizontal lines passed in, in @@ -160,11 +156,3 @@ ret _DrawHorizontalLineList endp end - - ------------------------ --------------------------------- -------------------- - [Previous](50-02.html) [Table of Contents](index.html) [Next](50-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/50-04.md b/50-04.md index 196ecd0..fb7a4ff 100644 --- a/50-04.md +++ b/50-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](50-03.html) [Table of Contents](index.html) [Next](50-05.html) - ------------------------ --------------------------------- -------------------- - The other 2-D element we need is some way to erase the polygon at its old location before it's moved and redrawn. We'll do that by remembering the bounding rectangle of the polygon each time it's drawn, then erasing @@ -127,11 +123,3 @@ but it will certainly reduce confusion! /* Draw the polygon */ DRAW_POLYGON(ProjectedPoly, PolyLength, Color, 0, 0); } - - ------------------------ --------------------------------- -------------------- - [Previous](50-03.html) [Table of Contents](index.html) [Next](50-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/50-05.md b/50-05.md index c05f2a0..3c1b795 100644 --- a/50-05.md +++ b/50-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](50-04.html) [Table of Contents](index.html) [Next](50-06.html) - ------------------------ --------------------------------- -------------------- - **LISTING 50.4 POLYGON.H** /* POLYGON.H: Header file for polygon-filling code, also includes @@ -76,11 +72,3 @@ int EndY, unsigned int PageBase, int Color); extern int DisplayedPage, NonDisplayedPage; extern struct Rect EraseRect[]; - - ------------------------ --------------------------------- -------------------- - [Previous](50-04.html) [Table of Contents](index.html) [Next](50-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/50-06.md b/50-06.md index d0cd0f1..be2e942 100644 --- a/50-06.md +++ b/50-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](50-05.html) [Table of Contents](index.html) [Next](50-07.html) - ------------------------ --------------------------------- -------------------- - **LISTING 50.5 L50-5.C** /* Simple 3-D drawing program to view a polygon as it rotates in @@ -124,11 +120,3 @@ regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */ int86(0x10, ®set, ®set); } - - ------------------------ --------------------------------- -------------------- - [Previous](50-05.html) [Table of Contents](index.html) [Next](50-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/50-07.md b/50-07.md index 214fbd3..be8e361 100644 --- a/50-07.md +++ b/50-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](50-06.html) [Table of Contents](index.html) [Next](51-01.html) - ------------------------ --------------------------------- -------------------- - #### Notes on the 3-D Animation Example {#Heading9} The sample program transforms the polygon's vertices from object space @@ -69,11 +65,3 @@ rotations than the simple rotation around the Y axis that we did this time. In time, we'll use fixed-point arithmetic to speed things up, and do some shading and texture mapping. The journey has only begun; we'll get to all that and more soon. - - ------------------------ --------------------------------- -------------------- - [Previous](50-06.html) [Table of Contents](index.html) [Next](51-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/51-01.md b/51-01.md index 70e92c3..3fadb48 100644 --- a/51-01.md +++ b/51-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](50-07.html) [Table of Contents](index.html) [Next](51-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 51\ Sneakers in Space {#Heading1} ------------------ @@ -86,11 +82,3 @@ polygons in an object could be instantly rejected by a test of this sort. Such testing of polygon visibility goes by a number of names in the literature, including backplane culling, backface removal, and assorted variations thereon; I'll refer to it as *backface removal*. - - ------------------------ --------------------------------- -------------------- - [Previous](50-07.html) [Table of Contents](index.html) [Next](51-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/51-02.md b/51-02.md index d073495..f70611b 100644 --- a/51-02.md +++ b/51-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](51-01.html) [Table of Contents](index.html) [Next](51-03.html) - ------------------------ --------------------------------- -------------------- - For a single convex polyhedron, removal of polygons that aren't facing the viewer would solve all hidden surface problems. In a convex polyhedron, any polygon facing the viewer can never be obscured by any @@ -107,11 +103,3 @@ subdirectory for this chapter on the listings diskette, whether they were presented in this chapter or some earlier chapter. This may crowd the listings diskette a little bit, but it will certainly reduce confusion! - - ------------------------ --------------------------------- -------------------- - [Previous](51-01.html) [Table of Contents](index.html) [Next](51-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/51-03.md b/51-03.md index 7242f98..f1347f4 100644 --- a/51-03.md +++ b/51-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](51-02.html) [Table of Contents](index.html) [Next](51-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 51.1 L51-1.C** /* 3D animation program to view a cube as it rotates in Mode X. The viewpoint @@ -164,11 +160,3 @@ regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */ int86(0x10, ®set, ®set); } - - ------------------------ --------------------------------- -------------------- - [Previous](51-02.html) [Table of Contents](index.html) [Next](51-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/51-04.md b/51-04.md index 2e46a32..66bb9f0 100644 --- a/51-04.md +++ b/51-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](51-03.html) [Table of Contents](index.html) [Next](51-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 51.2 L51-2.C** /* Transforms all vertices in the specified object into view spa ce, then @@ -137,11 +133,3 @@ those that had. ![](images/51-04.jpg)\ **Figure 51.4**  *The object data structure* - - ------------------------ --------------------------------- -------------------- - [Previous](51-03.html) [Table of Contents](index.html) [Next](51-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/51-05.md b/51-05.md index 782aba9..43ddac5 100644 --- a/51-05.md +++ b/51-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](51-04.html) [Table of Contents](index.html) [Next](51-06.html) - ------------------------ --------------------------------- -------------------- - With the above optimizations, the sample program is certainly adequately responsive on a 20 MHz 386 (sans 387; I'm sure it's wonderfully responsive with a math coprocessor). Still, it couldn't quite keep up @@ -99,11 +95,3 @@ eventually. XformToChange[0][2] = Temp02; XformToChange[1][0] = Temp10; XformToChange[1][1] = Temp11; XformToChange[1][2] = Temp12; } - - ------------------------ --------------------------------- -------------------- - [Previous](51-04.html) [Table of Contents](index.html) [Next](51-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/51-06.md b/51-06.md index 6991d0b..833b768 100644 --- a/51-06.md +++ b/51-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](51-05.html) [Table of Contents](index.html) [Next](52-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 51.5 POLYGON.H** /* POLYGON.H: Header file for polygon-filling code, also includes a number of @@ -124,11 +120,3 @@ space. It's not mandatory that vertices be stored for all these different spaces, but the coordinates in all those spaces have to be calculated as intermediate steps anyway, so we might as well keep them around for those occasions when they're needed. - - ------------------------ --------------------------------- -------------------- - [Previous](51-05.html) [Table of Contents](index.html) [Next](52-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/52-01.md b/52-01.md index 4861d37..c1f4bd2 100644 --- a/52-01.md +++ b/52-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](51-06.html) [Table of Contents](index.html) [Next](52-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 52\ Fast 3-D Animation: Meet X-Sharp {#Heading1} --------------------------------- @@ -84,11 +80,3 @@ program is the following: As always, all required files are in this chapter's subdirectory on the CD-ROM. - - ------------------------ --------------------------------- -------------------- - [Previous](51-06.html) [Table of Contents](index.html) [Next](52-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/52-02.md b/52-02.md index 1859ed7..e7a9fd1 100644 --- a/52-02.md +++ b/52-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](52-01.html) [Table of Contents](index.html) [Next](52-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 52.1 L52-1.C** /* 3-D animation program to rotate 12 cubes. Uses fixed point. All C code @@ -124,11 +120,3 @@ DOUBLE_TO_FIXED(0.5)) >> 16))) + SCREEN_HEIGHT/2; } } - - ------------------------ --------------------------------- -------------------- - [Previous](52-01.html) [Table of Contents](index.html) [Next](52-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/52-03.md b/52-03.md index 8c93515..37fd249 100644 --- a/52-03.md +++ b/52-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](52-02.html) [Table of Contents](index.html) [Next](52-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 52.3 L52-3.C** /* Routines to perform incremental rotations around the three axes. */ @@ -159,11 +155,3 @@ CubeVerts[i].Z = INT_TO_FIXED(IntCubeVerts[i].Z); } } - - ------------------------ --------------------------------- -------------------- - [Previous](52-02.html) [Table of Contents](index.html) [Next](52-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/52-04.md b/52-04.md index a97ad1b..31bac7c 100644 --- a/52-04.md +++ b/52-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](52-03.html) [Table of Contents](index.html) [Next](52-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 52.6 L52-6.C** /* Rotates and moves a polygon-based object around the three axes. @@ -101,11 +97,3 @@ } } } - - ------------------------ --------------------------------- -------------------- - [Previous](52-03.html) [Table of Contents](index.html) [Next](52-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/52-05.md b/52-05.md index 36fdf1b..6af5d67 100644 --- a/52-05.md +++ b/52-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](52-04.html) [Table of Contents](index.html) [Next](52-06.html) - ------------------------ --------------------------------- -------------------- - **LISTING 52.8 L52-8.C** /* Initializes the cubes and adds them to the object list. */ @@ -126,11 +122,3 @@ ObjectList[NumObjects++] = (Object *)WorkingCube; } } - - ------------------------ --------------------------------- -------------------- - [Previous](52-04.html) [Table of Contents](index.html) [Next](52-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/52-06.md b/52-06.md index d8967b3..56c4c5b 100644 --- a/52-06.md +++ b/52-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](52-05.html) [Table of Contents](index.html) [Next](52-07.html) - ------------------------ --------------------------------- -------------------- - **LISTING 52.9 L52-9.ASM** ; 386-specific fixed point multiply and divide. @@ -178,11 +174,3 @@ extern Xform WorldViewXform; extern Object *ObjectList[]; extern Point3 CubeVerts[]; - - ------------------------ --------------------------------- -------------------- - [Previous](52-05.html) [Table of Contents](index.html) [Next](52-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/52-07.md b/52-07.md index f2eecc1..b7aef90 100644 --- a/52-07.md +++ b/52-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](52-06.html) [Table of Contents](index.html) [Next](52-08.html) - ------------------------ --------------------------------- -------------------- - ### A New Animation Framework: X-Sharp {#Heading4} Listings 52.1 through 52.10 shown earlier represent not merely faster @@ -70,11 +66,3 @@ I'd like to point out, in case anyone missed it, that this is fully *general* 3-D. I'm not using any shortcuts or tricks, like prestoring coordinates or pregenerating bitmaps; if you were to feed in different rotations or vertices, the animation would change accordingly. - - ------------------------ --------------------------------- -------------------- - [Previous](52-06.html) [Table of Contents](index.html) [Next](52-08.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/52-08.md b/52-08.md index db86f25..cb544e7 100644 --- a/52-08.md +++ b/52-08.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [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 @@ -89,11 +85,3 @@ 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 diff --git a/53-01.md b/53-01.md index ca6b94b..d252096 100644 --- a/53-01.md +++ b/53-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](52-08.html) [Table of Contents](index.html) [Next](53-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 53\ Raw Speed and More {#Heading1} ------------------- @@ -78,11 +74,3 @@ altogether. FIXED.ASM is highly effective; the time taken for matrix math is now down to the point where it's a fairly minor component of execution time, representing less than ten percent of the total. It's time to turn our optimization sights elsewhere. - - ------------------------ --------------------------------- -------------------- - [Previous](52-08.html) [Table of Contents](index.html) [Next](53-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/53-02.md b/53-02.md index 27b15eb..1d72c90 100644 --- a/53-02.md +++ b/53-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](53-01.html) [Table of Contents](index.html) [Next](53-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 53.1 FIXED.ASM** ; 386-specific fixed point routines. @@ -391,11 +387,3 @@ ret -ConcatXformsendp end - - ------------------------ --------------------------------- -------------------- - [Previous](53-01.html) [Table of Contents](index.html) [Next](53-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/53-03.md b/53-03.md index bf3b065..0ab6dc1 100644 --- a/53-03.md +++ b/53-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](53-02.html) [Table of Contents](index.html) [Next](53-04.html) - ------------------------ --------------------------------- -------------------- - ### Raw Speed, Part II: Look it Up {#Heading4} It's a funny thing about Turbo Profiler: Time spent in the Borland C++ @@ -100,11 +96,3 @@ overlap in X and Y. ![](images/53-01.jpg)\ **Figure 53.1**  *Why back-to-front sorting doesn't always work properly.* - - ------------------------ --------------------------------- -------------------- - [Previous](53-02.html) [Table of Contents](index.html) [Next](53-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/53-04.md b/53-04.md index e796170..1700b7b 100644 --- a/53-04.md +++ b/53-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](53-03.html) [Table of Contents](index.html) [Next](54-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 53.2 OLIST.C** /* Object list-related functions. */ @@ -140,11 +136,3 @@ be nice to someday have an interactive 3-D object editing tool and resource management setup. We have our hands full with the drawing end of things at the moment, though, and for now it's enough to be able to create objects in a semiautomated way. - - ------------------------ --------------------------------- -------------------- - [Previous](53-03.html) [Table of Contents](index.html) [Next](54-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/54-01.md b/54-01.md index d741115..6367774 100644 --- a/54-01.md +++ b/54-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](53-04.html) [Table of Contents](index.html) [Next](54-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 54\ 3-D Shading {#Heading1} ------------ @@ -68,11 +64,3 @@ routine. In fact, it will generate a divide-by-zero error if passed a fixed-point divisor between -1 and 1. As I've explained, the non-386 version of **Fixed-Div()** is designed to do just what X-Sharp needs, and no more, as quickly as possible. - - ------------------------ --------------------------------- -------------------- - [Previous](53-04.html) [Table of Contents](index.html) [Next](54-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/54-02.md b/54-02.md index 1414129..4f3cd89 100644 --- a/54-02.md +++ b/54-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](54-01.html) [Table of Contents](index.html) [Next](54-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 54.1 FIXED.ASM** ; Fixed point routines. @@ -863,11 +859,3 @@ ret _ConcatXforms endp end - - ------------------------ --------------------------------- -------------------- - [Previous](54-01.html) [Table of Contents](index.html) [Next](54-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/54-03.md b/54-03.md index d43911a..82b3b39 100644 --- a/54-03.md +++ b/54-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](54-02.html) [Table of Contents](index.html) [Next](54-04.html) - ------------------------ --------------------------------- -------------------- - #### Shading {#Heading4} So far, the polygons out of which our animated objects have been built @@ -100,11 +96,3 @@ exactly as described by the above equation, first calculating the ambient red, green, and blue shadings, then summing that with the diffuse red, green, and blue shadings generated by each directed light source. - - ------------------------ --------------------------------- -------------------- - [Previous](54-02.html) [Table of Contents](index.html) [Next](54-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/54-04.md b/54-04.md index aff0bba..33fca92 100644 --- a/54-04.md +++ b/54-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](54-03.html) [Table of Contents](index.html) [Next](54-05.html) - ------------------------ --------------------------------- -------------------- - **LISTING 54.2 DRAWPOBJ.C** /* Draws all visible faces in the specified polygon-based object. The object @@ -130,11 +126,3 @@ } } } - - ------------------------ --------------------------------- -------------------- - [Previous](54-03.html) [Table of Contents](index.html) [Next](54-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/54-05.md b/54-05.md index eec7ba6..d9e4031 100644 --- a/54-05.md +++ b/54-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](54-04.html) [Table of Contents](index.html) [Next](55-01.html) - ------------------------ --------------------------------- -------------------- - #### Shading: Implementation Details {#Heading7} In order to calculate the cosine of the angle between an incoming light @@ -62,11 +58,3 @@ result of the restricted capabilities of the 256-color palette, and there is only so much that can be done without a larger color set. In the next chapter, I'll talk about some ways to improve the quality of 256-color shading. - - ------------------------ --------------------------------- -------------------- - [Previous](54-04.html) [Table of Contents](index.html) [Next](55-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/55-01.md b/55-01.md index dc79d2d..79620b2 100644 --- a/55-01.md +++ b/55-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](54-05.html) [Table of Contents](index.html) [Next](55-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 55\ Color Modeling in 256-Color Mode {#Heading1} --------------------------------- @@ -126,11 +122,3 @@ primary here. It's the brain that does the amazing part; the sensitivity in the eye, but rather from the brain's ability to distinguish between all the mixes of 256 levels of each of three primaries. - - ------------------------ --------------------------------- -------------------- - [Previous](54-05.html) [Table of Contents](index.html) [Next](55-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/55-02.md b/55-02.md index 6e19964..c57a1c6 100644 --- a/55-02.md +++ b/55-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](55-01.html) [Table of Contents](index.html) [Next](55-03.html) - ------------------------ --------------------------------- -------------------- - So it's perfectly reasonable to maintain 24 bits of color resolution, and X-Sharp represents colors internally as ideal, device-independent 24-bit RGB triplets. All shading calculations are performed on these @@ -123,11 +119,3 @@ that set up and perform the color mapping for DEMO1. sregset.es = DS; /* segment of array from which to load settings */ int86x(0x10, ®set, ®set, &sregset); /* load the palette block */ } - - ------------------------ --------------------------------- -------------------- - [Previous](55-01.html) [Table of Contents](index.html) [Next](55-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/55-03.md b/55-03.md index b7b45c8..1b7ba02 100644 --- a/55-03.md +++ b/55-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](55-02.html) [Table of Contents](index.html) [Next](55-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 55.3 L55-3.C** /* Converts a model color (a color in the RGB color cube, in the current @@ -128,11 +124,3 @@ bit-by-bit basis. The latches solve half our problem; we can fill the latches with the background color, then use them to draw the background box. The trick now is drawing the text pixels in the foreground color at the same time. - - ------------------------ --------------------------------- -------------------- - [Previous](55-02.html) [Table of Contents](index.html) [Next](55-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/55-04.md b/55-04.md index d24ba3b..8f2be6c 100644 --- a/55-04.md +++ b/55-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](55-03.html) [Table of Contents](index.html) [Next](56-01.html) - ------------------------ --------------------------------- -------------------- - This is where it gets a little complicated. In write mode 3 (which incidentally is not available on the EGA), each byte value that the CPU writes to the VGA does not get written to display memory. Instead, it @@ -212,11 +208,3 @@ but is considerably more difficult to apply. ret DrawTextString endp end start - - ------------------------ --------------------------------- -------------------- - [Previous](55-03.html) [Table of Contents](index.html) [Next](56-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/56-01.md b/56-01.md index acc8843..cdd91a5 100644 --- a/56-01.md +++ b/56-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](55-04.html) [Table of Contents](index.html) [Next](56-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 56\ Pooh and the Space Station {#Heading1} --------------------------- @@ -127,11 +123,3 @@ polygon, we'll select the corresponding edge in the source bitmap, as well. Then—and this is crucial—each time we step a destination edge one scan line, we'll step the corresponding source image edge an equivalent amount. - - ------------------------ --------------------------------- -------------------- - [Previous](55-04.html) [Table of Contents](index.html) [Next](56-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/56-02.md b/56-02.md index 7eef069..4778593 100644 --- a/56-02.md +++ b/56-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](56-01.html) [Table of Contents](index.html) [Next](56-03.html) - ------------------------ --------------------------------- -------------------- - Ah, but what is an "equivalent amount"? Think of it this way. If a destination edge is 100 scan lines high, it will be stepped 100 times. Then, we'll divide the **SourceXWidth** and **SourceYHeight** lengths of @@ -120,11 +116,3 @@ constraints of the PC's horsepower. Next, we'll look at code that performs DDA texture mapping. First, though, I'd like to take a moment to thank Jim Kent, author of Autodesk Animator and a frequent correspondent, for getting me started with the DDA approach. - - ------------------------ --------------------------------- -------------------- - [Previous](56-01.html) [Table of Contents](index.html) [Next](56-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/56-03.md b/56-03.md index a60c7a4..67e1958 100644 --- a/56-03.md +++ b/56-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](56-02.html) [Table of Contents](index.html) [Next](57-01.html) - ------------------------ --------------------------------- -------------------- - ### Fast Texture Mapping: An Implementation {#Heading6} As you might expect, I've implemented DDA texture mapping in X-Sharp, @@ -341,11 +337,3 @@ does tend to look a little startled when you flip the ball around so that he's zipping by on his head, but, heck, you would too in the same situation. And remember, when you buy the next VGA megahit, *Bears in Space*, you saw it here first. - - ------------------------ --------------------------------- -------------------- - [Previous](56-02.html) [Table of Contents](index.html) [Next](57-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/57-01.md b/57-01.md index e101037..b2353fc 100644 --- a/57-01.md +++ b/57-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](56-03.html) [Table of Contents](index.html) [Next](57-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 57\ 10,000 Freshly Sheared Sheep on the Screen {#Heading1} ------------------------------------------- @@ -123,11 +119,3 @@ texture-mapping process, a one-pixel mapping error is insignificant. Experience again: It's the difference between knowing which flaws (like small texture shifts) can reasonably be ignored, and which (like those that produce gaps between polygons) must be avoided at all costs. - - ------------------------ --------------------------------- -------------------- - [Previous](56-03.html) [Table of Contents](index.html) [Next](57-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/57-02.md b/57-02.md index bf5fad1..2682c9a 100644 --- a/57-02.md +++ b/57-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](57-01.html) [Table of Contents](index.html) [Next](57-03.html) - ------------------------ --------------------------------- -------------------- - #### Texture Mapping: Orientation Independence {#Heading5} The double-DDA texture-mapping code presented in the previous chapter @@ -155,11 +151,3 @@ inner loop for texture-mapped polygon drawing; Listing 57.2 is only the code to draw a single scan line. Most of the work in drawing a texture-mapped polygon comes in scanning out individual lines, though, so this is the appropriate place to optimize. - - ------------------------ --------------------------------- -------------------- - [Previous](57-01.html) [Table of Contents](index.html) [Next](57-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/57-03.md b/57-03.md index f5924da..78f51b3 100644 --- a/57-03.md +++ b/57-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](57-02.html) [Table of Contents](index.html) [Next](57-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 57.2 L57-2.ASM** ; Draws all pixels in the specified scan line, with the pixel colors @@ -302,11 +298,3 @@ ret -ScanOutLine endp end - - ------------------------ --------------------------------- -------------------- - [Previous](57-02.html) [Table of Contents](index.html) [Next](57-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/57-04.md b/57-04.md index f6f68c8..29a5555 100644 --- a/57-04.md +++ b/57-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](57-03.html) [Table of Contents](index.html) [Next](58-01.html) - ------------------------ --------------------------------- -------------------- - Within Listing 57.2, all the important optimization is in the loop that draws across each destination scan line, near the end of the listing. One optimization is elimination of the call to the set-pixel routine @@ -63,11 +59,3 @@ I'm always interested in getting your feedback on and hearing about potential improvements to X-Sharp. Contact me through the publisher. There is no truth to the rumor that I can be reached under the alias "sheep-shearer," at least not for another 9,999 sheep. - - ------------------------ --------------------------------- -------------------- - [Previous](57-03.html) [Table of Contents](index.html) [Next](58-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/58-01.md b/58-01.md index 157d779..aa51ed4 100644 --- a/58-01.md +++ b/58-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](57-04.html) [Table of Contents](index.html) [Next](58-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 58\ Heinlein's Crystal Ball, Spock's Brain, and the 9-Cycle Dare {#Heading1} ------------------------------------------------------------- @@ -123,11 +119,3 @@ as I had to cycle from one plane to the next for every pixel. ![](images/58-01.jpg)\ **Figure 58.1**  *Texture mapping a single horizontal scanline.* - - ------------------------ --------------------------------- -------------------- - [Previous](57-04.html) [Table of Contents](index.html) [Next](58-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/58-02.md b/58-02.md index 8d3a8dd..1351b0f 100644 --- a/58-02.md +++ b/58-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](58-01.html) [Table of Contents](index.html) [Next](58-03.html) - ------------------------ --------------------------------- -------------------- - **LISTING 58.1 L58-1.ASM** ; Inner loop to draw a single texture-mapped horizontal scanline in @@ -158,11 +154,3 @@ of *four* times faster than Listing 58.1.) adc di,dx ENDM - - ------------------------ --------------------------------- -------------------- - [Previous](58-01.html) [Table of Contents](index.html) [Next](58-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/58-03.md b/58-03.md index 1b8ec74..9aa0040 100644 --- a/58-03.md +++ b/58-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](58-02.html) [Table of Contents](index.html) [Next](58-04.html) - ------------------------ --------------------------------- -------------------- - I'd like to emphasize that algorithmically and conceptually, there is *no* difference between scanning out a polygon top to bottom and scanning it out left to right; it is only in conjunction with the @@ -134,11 +130,3 @@ can't get away with just adding in the carry from the Y fractional addition, because when the Y fraction carries, it indicates a move not from one pixel to the next on a scanline (a single byte), but rather from one scanline to the next (a full scanline width). - - ------------------------ --------------------------------- -------------------- - [Previous](58-02.html) [Table of Contents](index.html) [Next](58-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/58-04.md b/58-04.md index d68a482..56d24cc 100644 --- a/58-04.md +++ b/58-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](58-03.html) [Table of Contents](index.html) [Next](58-05.html) - ------------------------ --------------------------------- -------------------- - All of the above optimizations together get us to 10 cycles—*very* close to John Miles, but not there yet. We have one more trick up our sleeve, though: Suppose we point SS to the segment containing our textures, and @@ -96,11 +92,3 @@ reduce performance below the calculated 8-cycles-per-pixel level, especially because textures, which can be scanned across at any angle, are rarely accessed at consecutive addresses, which is the arrangement that would make for the fewest cache misses. - - ------------------------ --------------------------------- -------------------- - [Previous](58-03.html) [Table of Contents](index.html) [Next](58-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/58-05.md b/58-05.md index 52155fa..7895d4e 100644 --- a/58-05.md +++ b/58-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](58-04.html) [Table of Contents](index.html) [Next](59-01.html) - ------------------------ --------------------------------- -------------------- - **LISTING 58.4 L58-4.ASM** ; Inner loop to draw a single texture-mapped vertical column, @@ -99,11 +95,3 @@ to make me *believe* a texture mapper could run that fast. Believe it! And while you're at it, give both halves of your brain equal time—and watch out for aliens in short skirts, 60's bouffant hairdos, and an undue interest in either half. - - ------------------------ --------------------------------- -------------------- - [Previous](58-04.html) [Table of Contents](index.html) [Next](59-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/59-01.md b/59-01.md index 08ccf51..f9ebacd 100644 --- a/59-01.md +++ b/59-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](58-05.html) [Table of Contents](index.html) [Next](59-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 59\ The Idea of BSP Trees {#Heading1} ---------------------- @@ -129,11 +125,3 @@ remembering which pixels have already been drawn. The latter approach is more complex, but has the potential benefit of allowing you to early-out from traversal of the scene database when all the pixels on the screen have been drawn. - - ------------------------ --------------------------------- -------------------- - [Previous](58-05.html) [Table of Contents](index.html) [Next](59-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/59-02.md b/59-02.md index 2157537..31de0bc 100644 --- a/59-02.md +++ b/59-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](59-01.html) [Table of Contents](index.html) [Next](59-03.html) - ------------------------ --------------------------------- -------------------- - Back-to-front or front-to-back traversal in itself wouldn't be so impressive—there are many ways to do that—were it not for one additional detail: The traversal can always be performed in linear time, as we'll @@ -115,11 +111,3 @@ splitting line doesn't actually create a unique subspace for each wall, but it does create a unique subspace *boundary* for each wall; as we'll see, that spatial organization provides for the same unambiguous visibility ordering as a unique subspace would.) - - ------------------------ --------------------------------- -------------------- - [Previous](59-01.html) [Table of Contents](index.html) [Next](59-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/59-03.md b/59-03.md index b2b554e..324277f 100644 --- a/59-03.md +++ b/59-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](59-02.html) [Table of Contents](index.html) [Next](59-04.html) - ------------------------ --------------------------------- -------------------- - Creating a BSP tree is a recursive process, so we'll perform the first split and go from there. Figure 59.3 shows the world carved along the line of wall C into two parts: walls that are in front of wall C, and @@ -131,11 +127,3 @@ of the left and right vertices indicates which way the wall is facing. ------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ![](images/i.jpg) *Be aware that BSP trees can often be made smaller and more efficient by detecting collinear surfaces (like aligned wall segments) and generating only one BSP node for each collinear set, with the collinear surfaces stored in, say, a linked list attached to that node. Collinear surfaces partition space identically and can't occlude one another, so it suffices to generate one splitting node for each collinear set.* ------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - ------------------------ --------------------------------- -------------------- - [Previous](59-02.html) [Table of Contents](index.html) [Next](59-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/59-04.md b/59-04.md index a6105d7..89bce99 100644 --- a/59-04.md +++ b/59-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](59-03.html) [Table of Contents](index.html) [Next](59-05.html) - ------------------------ --------------------------------- -------------------- - ### Inorder Walks of BSP Trees {#Heading8} It was implementing BSP trees that got me to thinking about inorder tree @@ -175,11 +171,3 @@ Listing 59.4, working with the code-recursive version as a model. } } } - - ------------------------ --------------------------------- -------------------- - [Previous](59-03.html) [Table of Contents](index.html) [Next](59-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/59-05.md b/59-05.md index 28f1020..08ba387 100644 --- a/59-05.md +++ b/59-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](59-04.html) [Table of Contents](index.html) [Next](59-06.html) - ------------------------ --------------------------------- -------------------- - Take a few minutes to look over Listing 59.4 and relate it to Listing 59.2. The structure is different, but upon examination it becomes clear that both listings reflect the same underlying model: For each node, @@ -112,11 +108,3 @@ measuring!) { VisitCount++; } - - ------------------------ --------------------------------- -------------------- - [Previous](59-04.html) [Table of Contents](index.html) [Next](59-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/59-06.md b/59-06.md index 77c9bd1..3d00203 100644 --- a/59-06.md +++ b/59-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](59-05.html) [Table of Contents](index.html) [Next](60-01.html) - ------------------------ --------------------------------- -------------------- - Things change when maximum optimization is selected, however: The performance of the two implementations becomes virtually identical! How can this be? Part of the answer is that the compiler does an amazingly @@ -89,11 +85,3 @@ Computer Graphics and Applications,* September 1991, pp. 79-85. Naylor, B., "Binary Space Partitioning Trees as an Alternative Representation of Polytopes," *Computer Aided Design*, Vol. 22(4), May 1990, pp. 250-253. - - ------------------------ --------------------------------- -------------------- - [Previous](59-05.html) [Table of Contents](index.html) [Next](60-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/60-01.md b/60-01.md index 75e0190..59824d5 100644 --- a/60-01.md +++ b/60-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](59-06.html) [Table of Contents](index.html) [Next](60-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 60\ Compiling BSP Trees {#Heading1} -------------------- @@ -116,11 +112,3 @@ parts, and so on, with each surface carving ever smaller subspaces, until all surfaces have been used. (Actually, there are many other lines or planes that a BSP tree can use to carve up space, but this is the approach we'll use in the current discussion.) - - ------------------------ --------------------------------- -------------------- - [Previous](59-06.html) [Table of Contents](index.html) [Next](60-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/60-02.md b/60-02.md index 772ab8b..4baec08 100644 --- a/60-02.md +++ b/60-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](60-01.html) [Table of Contents](index.html) [Next](60-03.html) - ------------------------ --------------------------------- -------------------- - If you find any of the above confusing (and it would be understandable if that were the case; BSP trees are not easy to get the hang of), you might want to refer back to the previous chapter. It would also be a @@ -134,11 +130,3 @@ nodes. **SelectBSP()** uses parametric clipping to decide on the splitter, as described below, and **BuildBSPTree()** uses parametric clipping to decide which subspace of the splitter each line belongs in, and to split lines, if necessary. - - ------------------------ --------------------------------- -------------------- - [Previous](60-01.html) [Table of Contents](index.html) [Next](60-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/60-03.md b/60-03.md index 9210efc..fc2c587 100644 --- a/60-03.md +++ b/60-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](60-02.html) [Table of Contents](index.html) [Next](60-04.html) - ------------------------ --------------------------------- -------------------- - **Listing 60.1 L60\_1.CPP** #define MAX_NUM_LINESEGS 1000 @@ -261,11 +257,3 @@ } return(prootline); } - - ------------------------ --------------------------------- -------------------- - [Previous](60-02.html) [Table of Contents](index.html) [Next](60-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/60-04.md b/60-04.md index 9bb85cc..d63b9ae 100644 --- a/60-04.md +++ b/60-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](60-03.html) [Table of Contents](index.html) [Next](61-01.html) - ------------------------ --------------------------------- -------------------- - Listing 60.1 isn't very long or complex, but it's somewhat more complicated than it could be because it's structured to allow visual display of the ongoing compilation process. That's because Listing 60.1 @@ -79,11 +75,3 @@ strike paydirt. There are many things that BSP trees can't do well, because it takes so long to build them—but what they do, they do exceedingly well, so a better compilation approach that allowed BSP trees to be used for more purposes would be valuable, indeed. - - ------------------------ --------------------------------- -------------------- - [Previous](60-03.html) [Table of Contents](index.html) [Next](61-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/61-01.md b/61-01.md index f525c86..5e6d59f 100644 --- a/61-01.md +++ b/61-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](60-04.html) [Table of Contents](index.html) [Next](61-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 61\ Frames of Reference {#Heading1} -------------------- @@ -106,11 +102,3 @@ magnitude, by the Pythagorean theorem, of (where vertical double bars denote vector length), and a direction in the plane of the x and z axes, exactly halfway between those two axes. - - ------------------------ --------------------------------- -------------------- - [Previous](60-04.html) [Table of Contents](index.html) [Next](61-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/61-02.md b/61-02.md index d5cd2a1..23a1831 100644 --- a/61-02.md +++ b/61-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](61-01.html) [Table of Contents](index.html) [Next](61-03.html) - ------------------------ --------------------------------- -------------------- - I'll be working in a left-handed coordinate system, whereby if you wrap the fingers of your left hand around the z axis with your thumb pointing in the positive z direction, your fingers will curl from the positive x @@ -117,11 +113,3 @@ are no longer normals in screenspace. ![](images/61-02.jpg)\ **Figure 61.2**  *The dot product as used in calculating lighting intensity.* - - ------------------------ --------------------------------- -------------------- - [Previous](61-01.html) [Table of Contents](index.html) [Next](61-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/61-03.md b/61-03.md index b30df27..3da02f3 100644 --- a/61-03.md +++ b/61-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](61-02.html) [Table of Contents](index.html) [Next](61-04.html) - ------------------------ --------------------------------- -------------------- - Why does this matter? It matters because, on average, half the polygons in any scene are facing away from the viewer, and hence shouldn't be drawn. One way to identify such polygons is to see whether they're @@ -107,11 +103,3 @@ understand the use of the dot product for projection. ![](images/61-05.jpg)\ **Figure 61.5**  *Backface culling with the dot product.* - - ------------------------ --------------------------------- -------------------- - [Previous](61-02.html) [Table of Contents](index.html) [Next](61-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/61-04.md b/61-04.md index 2caa62b..dfa4ccd 100644 --- a/61-04.md +++ b/61-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](61-03.html) [Table of Contents](index.html) [Next](62-01.html) - ------------------------ --------------------------------- -------------------- - ### Using the Dot Product for Projection {#Heading9} Consider Equation 3 again, but this time make one of the vectors, say @@ -114,11 +110,3 @@ in general, offer those sorts of benefits for 3-D. ![](images/61-08.jpg)\ **Figure 61.8**  *Rotation to a new coordinate space by projection onto new axes.* - - ------------------------ --------------------------------- -------------------- - [Previous](61-03.html) [Table of Contents](index.html) [Next](62-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/62-01.md b/62-01.md index f386ab5..a4c4fea 100644 --- a/62-01.md +++ b/62-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](61-04.html) [Table of Contents](index.html) [Next](62-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 62\ One Story, Two Rules, and a BSP Renderer {#Heading1} ----------------------------------------- @@ -104,11 +100,3 @@ framework, some math routines, and the polygon rasterizer; but, the entire program is on the CD-ROM as DDJBSP2.ZIP. Listing 62.1 is in a compressed format, with relatively little whitespace; the full version on the CD-ROM is formatted normally.) - - ------------------------ --------------------------------- -------------------- - [Previous](61-04.html) [Table of Contents](index.html) [Next](62-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/62-02.md b/62-02.md index 57de319..49495a3 100644 --- a/62-02.md +++ b/62-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](62-01.html) [Table of Contents](index.html) [Next](62-03.html) - ------------------------ --------------------------------- -------------------- - **Listing 62.1 L62\_1.C** /* Core renderer for Win32 program to demonstrate drawing from a 2-D @@ -443,11 +439,3 @@ ReleaseDC(hwndOutput, hdcDIBSection); iteration++; } - - ------------------------ --------------------------------- -------------------- - [Previous](62-01.html) [Table of Contents](index.html) [Next](62-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/62-03.md b/62-03.md index 12dcf51..f741ea7 100644 --- a/62-03.md +++ b/62-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](62-02.html) [Table of Contents](index.html) [Next](62-04.html) - ------------------------ --------------------------------- -------------------- - #### The Rendering Pipeline {#Heading4} Conceptually rendering from a BSP tree really is that simple, but the @@ -128,11 +124,3 @@ as the last step for visible walls in **ClipWalls()**. ![](images/62-03.jpg)\ **Figure 62.3**  *Why y clipping is more complex than x or z clipping.* - - ------------------------ --------------------------------- -------------------- - [Previous](62-02.html) [Table of Contents](index.html) [Next](62-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/62-04.md b/62-04.md index 5187d69..2d2c1a9 100644 --- a/62-04.md +++ b/62-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](62-03.html) [Table of Contents](index.html) [Next](63-01.html) - ------------------------ --------------------------------- -------------------- - ### Walking the Tree, Backface Culling and Drawing {#Heading9} Now that we have all the walls clipped to the frustum, with vertices @@ -98,11 +94,3 @@ detecting collisions, doing line-of-sight determination, and performing volume-based operations such as dynamic illumination and event triggering. However, that discussion will have to wait until another day. - - ------------------------ --------------------------------- -------------------- - [Previous](62-03.html) [Table of Contents](index.html) [Next](63-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/63-01.md b/63-01.md index 367d0c1..1eb78f4 100644 --- a/63-01.md +++ b/63-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](62-04.html) [Table of Contents](index.html) [Next](63-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 63\ Floating-Point for Real-Time 3-D {#Heading1} --------------------------------- @@ -139,11 +135,3 @@ instructions. FLD takes 1 cycle; the value is pushed onto the FP stack and ready for use on the next cycle. FST takes 2 cycles, although when storing to memory, there's a potential extra cycle that can be lost, as I'll describe shortly. - - ------------------------ --------------------------------- -------------------- - [Previous](62-04.html) [Table of Contents](index.html) [Next](63-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/63-02.md b/63-02.md index 36c6825..98037f3 100644 --- a/63-02.md +++ b/63-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](63-01.html) [Table of Contents](index.html) [Next](63-03.html) - ------------------------ --------------------------------- -------------------- - FDIV is a painfully slow instruction, taking 39 cycles at full precision and 33 cycles at double precision, which is the default precision for Visual C++ 2.0. While FDIV executes, the FPU is occupied, and can't @@ -155,11 +151,3 @@ unless some other code is available to be interleaved with the dot product code, that's all we can do to speed things up. Fortunately, dot products are often used in contexts where there's plenty of interleaving potential, as we'll see when we discuss transformation. - - ------------------------ --------------------------------- -------------------- - [Previous](63-01.html) [Table of Contents](index.html) [Next](63-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/63-03.md b/63-03.md index 3594596..ad268d3 100644 --- a/63-03.md +++ b/63-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](63-02.html) [Table of Contents](index.html) [Next](63-04.html) - ------------------------ --------------------------------- -------------------- - **Listing 63.2 1 L63-2.ASM** ; unoptimized dot product; 17 cycles @@ -144,11 +140,3 @@ or v1 = m11u1 + m12u2 + m13u3 + m14 v2 = m21u1 + m22u2 + m23u3 + m24 v3 = m31u1 + m32u2 + m33u3 + m34. - - ------------------------ --------------------------------- -------------------- - [Previous](63-02.html) [Table of Contents](index.html) [Next](63-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/63-04.md b/63-04.md index 9535219..fb1b424 100644 --- a/63-04.md +++ b/63-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](63-03.html) [Table of Contents](index.html) [Next](64-01.html) - ------------------------ --------------------------------- -------------------- - When it comes to implementation, however, transformation is quite different from three separate dot products and additions, because once again the magic number *three* is involved. Three separate dot products @@ -121,11 +117,3 @@ floating-point is fast enough for real time, I don't expect to be doing a whole lot of fixed-point 3-D math from here on out. And I won't miss it a bit. - - ------------------------ --------------------------------- -------------------- - [Previous](63-03.html) [Table of Contents](index.html) [Next](64-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/64-01.md b/64-01.md index 39e604a..7cb9751 100644 --- a/64-01.md +++ b/64-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](63-04.html) [Table of Contents](index.html) [Next](64-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 64\ Quake's Visible-Surface Determination {#Heading1} -------------------------------------- @@ -104,11 +100,3 @@ PC 3-D over the next few years, as 3-D worlds become increasingly detailed. Already, a good-sized Quake level contains on the order of 10,000 polygons, about three times as many polygons as a comparable DOOM level. - - ------------------------ --------------------------------- -------------------- - [Previous](63-04.html) [Table of Contents](index.html) [Next](64-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/64-02.md b/64-02.md index ad76e20..1c4085e 100644 --- a/64-02.md +++ b/64-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](64-01.html) [Table of Contents](index.html) [Next](64-03.html) - ------------------------ --------------------------------- -------------------- - ### The Structure of Quake Levels {#Heading4} Before diving into VSD, let me note that each Quake level is stored as a @@ -126,11 +122,3 @@ shipped the product. By three months after I arrived, only one element of the original VSD design was anywhere in sight, and John had taken the dictum of "try new things" farther than I'd ever seen it taken. - - ------------------------ --------------------------------- -------------------- - [Previous](64-01.html) [Table of Contents](index.html) [Next](64-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/64-03.md b/64-03.md index 88051ae..6e60d6d 100644 --- a/64-03.md +++ b/64-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](64-02.html) [Table of Contents](index.html) [Next](64-04.html) - ------------------------ --------------------------------- -------------------- - ### The Beam Tree {#Heading8} John's original Quake design was to draw front-to-back, using a second @@ -141,11 +137,3 @@ code. Although the direct-BSP approach was getting closer to working, it was taking more and more tweaking, and a simple, clean design didn't seem to be falling out. When I left work one Friday, John was preparing to try to get the direct-BSP approach working properly over the weekend. - - ------------------------ --------------------------------- -------------------- - [Previous](64-02.html) [Table of Contents](index.html) [Next](64-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/64-04.md b/64-04.md index 8017ecb..05a7381 100644 --- a/64-04.md +++ b/64-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](64-03.html) [Table of Contents](index.html) [Next](65-01.html) - ------------------------ --------------------------------- -------------------- - When I came in on Monday, John had the look of a man who had broken through to the other side—and also the look of a man who hadn't had much sleep. He had worked all weekend on the direct-BSP approach, and had @@ -123,11 +119,3 @@ along with several other papers relevant to visibility determination. Teller, Seth, *Visibility Preprocessing for Interactive Walkthroughs*, SIGGRAPH 91 proceedings, pp. 61-69. - - ------------------------ --------------------------------- -------------------- - [Previous](64-03.html) [Table of Contents](index.html) [Next](65-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/65-01.md b/65-01.md index 245ce95..6b8ae70 100644 --- a/65-01.md +++ b/65-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](64-04.html) [Table of Contents](index.html) [Next](65-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 65\ 3-D Clipping and Other Thoughts {#Heading1} -------------------------------- @@ -129,11 +125,3 @@ the stuff I wish I'd known when I started doing 3-D. There are plenty of ways to speed up clipping under various circumstances, some of which I'll mention, but the material covered below will give you the tools you need to implement functional 3-D clipping. - - ------------------------ --------------------------------- -------------------- - [Previous](64-04.html) [Table of Contents](index.html) [Next](65-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/65-02.md b/65-02.md index e07dc95..37e19e0 100644 --- a/65-02.md +++ b/65-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](65-01.html) [Table of Contents](index.html) [Next](65-03.html) - ------------------------ --------------------------------- -------------------- - #### Intersecting a Line Segment with a Plane {#Heading4} The fundamental 3-D clipping operation is clipping a line segment to a @@ -140,11 +136,3 @@ measured along the normal.* ![](images/65-02.jpg)\ **Figure 65.2**  *Clipping a polygon.* - - ------------------------ --------------------------------- -------------------- - [Previous](65-01.html) [Table of Contents](index.html) [Next](65-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/65-03.md b/65-03.md index 7b226ce..1cb487a 100644 --- a/65-03.md +++ b/65-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](65-02.html) [Table of Contents](index.html) [Next](65-04.html) - ------------------------ --------------------------------- -------------------- - **LISTING 65.2 L65\_2.c** int ClipToPlane(polygon_t *pin, plane_t *pplane, polygon_t *pout) @@ -391,11 +387,3 @@ is available on the CD-ROM in the file DDJCLIP.ZIP. SelectObject(hdcDIBSection, holdbitmap); ReleaseDC(hwndOutput, hdcDIBSection); } - - ------------------------ --------------------------------- -------------------- - [Previous](65-02.html) [Table of Contents](index.html) [Next](65-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/65-04.md b/65-04.md index 817456c..bbbfe9a 100644 --- a/65-04.md +++ b/65-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](65-03.html) [Table of Contents](index.html) [Next](66-01.html) - ------------------------ --------------------------------- -------------------- - #### The Lessons of Listing 65.3 {#Heading7} There are several interesting points to Listing 65.3. First, @@ -118,11 +114,3 @@ is that anyone who's interested can tap into so much expert knowledge for the price of a book—or, on the Internet, for free—with no strings attached. Our part of the world is a pretty good place right now, isn't it? - - ------------------------ --------------------------------- -------------------- - [Previous](65-03.html) [Table of Contents](index.html) [Next](66-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/66-01.md b/66-01.md index 0f30ff7..608e849 100644 --- a/66-01.md +++ b/66-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](65-04.html) [Table of Contents](index.html) [Next](66-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 66\ Quake's Hidden-Surface Removal {#Heading1} ------------------------------- @@ -120,11 +116,3 @@ moving objects. For the rest of this chapter, I'm going to talk about the other part of the drawing equation; that is, how to draw the world itself, where the entire world is stored as a single BSP tree and never moves. - - ------------------------ --------------------------------- -------------------- - [Previous](65-04.html) [Table of Contents](index.html) [Next](66-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/66-02.md b/66-02.md index 694ef78..2210a65 100644 --- a/66-02.md +++ b/66-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](66-01.html) [Table of Contents](index.html) [Next](66-03.html) - ------------------------ --------------------------------- -------------------- - As you may recall from Chapter 64, we're concerned with both raw performance and level performance. That is, we want the drawing code to run as fast as possible, but we also want the difference in drawing @@ -118,11 +114,3 @@ step to a new scan line, edges that end on that scan line are removed from the AEL, active edges are stepped to their new x coordinates, edges starting on the new scan line are added to the AEL, and the edges are sorted by current x coordinate. - - ------------------------ --------------------------------- -------------------- - [Previous](66-01.html) [Table of Contents](index.html) [Next](66-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/66-03.md b/66-03.md index ac77778..bf3a505 100644 --- a/66-03.md +++ b/66-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](66-02.html) [Table of Contents](index.html) [Next](66-04.html) - ------------------------ --------------------------------- -------------------- - For each scan line, a z-sorted active polygon list (APL) is maintained. The x-sorted AEL is stepped through in order. As each new edge is encountered (that is, as each polygon starts or ends as we move left to @@ -120,11 +116,3 @@ linearity and gradients for 1/z.) Another advantage of using 1/z is that its resolution increases with decreasing distance, meaning that by using 1/z, we'll have better depth resolution for nearby features, where it matters most. - - ------------------------ --------------------------------- -------------------- - [Previous](66-02.html) [Table of Contents](index.html) [Next](66-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/66-04.md b/66-04.md index 99ec40a..7b8d92b 100644 --- a/66-04.md +++ b/66-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](66-03.html) [Table of Contents](index.html) [Next](67-01.html) - ------------------------ --------------------------------- -------------------- - The obvious way to get a 1/z value at any arbitrary point on a polygon is to calculate 1/z at the vertices, interpolate it down both edges of the polygon, and interpolate between the edges to get the value at the @@ -94,11 +90,3 @@ graphics engines as often as they play Elvis on the ‘50s oldies stations (but, one would hope, with more aesthetically pleasing results!) and no doubt we'll be considering the alternatives right up until the day we ship. - - ------------------------ --------------------------------- -------------------- - [Previous](66-03.html) [Table of Contents](index.html) [Next](67-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/67-01.md b/67-01.md index 862f290..3bf543d 100644 --- a/67-01.md +++ b/67-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](66-04.html) [Table of Contents](index.html) [Next](67-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 67\ Sorted Spans in Action {#Heading1} ----------------------- @@ -112,11 +108,3 @@ We tinkered with those too, adding more code and incurring additional slowdowns in the process. Finally, we had everything working smoothly again, although by this point Quake was back to pretty much the same speed it had been with BSP sorting. - - ------------------------ --------------------------------- -------------------- - [Previous](66-04.html) [Table of Contents](index.html) [Next](67-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/67-02.md b/67-02.md index db195d9..364dd3a 100644 --- a/67-02.md +++ b/67-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](67-01.html) [Table of Contents](index.html) [Next](67-03.html) - ------------------------ --------------------------------- -------------------- - And then yet another crop of sorting errors popped up. We could have fixed those errors too; we'll take a quick look at how to @@ -121,11 +117,3 @@ same order throughout a scene. However, in Quake at least, the benefits of caching sort results were outweighed by the additional overhead of maintaining the caching information, and every caching variant we tried actually slowed Quake down. - - ------------------------ --------------------------------- -------------------- - [Previous](67-01.html) [Table of Contents](index.html) [Next](67-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/67-03.md b/67-03.md index 3dc576a..4f091b7 100644 --- a/67-03.md +++ b/67-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](67-02.html) [Table of Contents](index.html) [Next](67-04.html) - ------------------------ --------------------------------- -------------------- - #### Independent Span Sorting {#Heading7} Finally, we come to independent span sorting, the simplest and fastest @@ -467,11 +463,3 @@ for real-world applications than the 3-D clipping demo from Chapter 65. SelectObject(hdcDIBSection, holdbitmap); DeleteDC(hdcDIBSection); } - - ------------------------ --------------------------------- -------------------- - [Previous](67-02.html) [Table of Contents](index.html) [Next](67-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/67-04.md b/67-04.md index 97b011a..56af441 100644 --- a/67-04.md +++ b/67-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](67-03.html) [Table of Contents](index.html) [Next](67-05.html) - ------------------------ --------------------------------- -------------------- - By the same token, Listing 67.1 is quite a bit more complicated than the earlier code. The earlier code's HSR consisted of a z-sort of objects, followed by the drawing of the objects in back-to-front order, one @@ -83,11 +79,3 @@ to be removed from the surface stack, again with a span emitted if necessary. As you can see from Listing 67.1, it takes a fair bit of code to implement this, but all that's really going on is a surface stack driven by edge events. - - ------------------------ --------------------------------- -------------------- - [Previous](67-03.html) [Table of Contents](index.html) [Next](67-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/67-05.md b/67-05.md index f3a5404..5a31768 100644 --- a/67-05.md +++ b/67-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](67-04.html) [Table of Contents](index.html) [Next](68-01.html) - ------------------------ --------------------------------- -------------------- - #### Implementation Notes {#Heading9} Finally, a few notes on Listing 67.1. First, you'll notice that although @@ -67,11 +63,3 @@ were based directly on the viewing angle, rather than on the dot product of a viewing ray to the polygon with the polygon normal, but that would require a square root, and in my experience the epsilon used in Listing 67.1 works fine. - - ------------------------ --------------------------------- -------------------- - [Previous](67-04.html) [Table of Contents](index.html) [Next](68-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/68-01.md b/68-01.md index 297c904..37e8091 100644 --- a/68-01.md +++ b/68-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](67-05.html) [Table of Contents](index.html) [Next](68-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 68\ Quake's Lighting Model {#Heading1} ----------------------- @@ -125,11 +121,3 @@ and creating new polygons wherever a spotlight was directly overhead a polygon, with the new vertex added directly underneath the light, as shown in Figure 68.1. This produced fairly attractive highlights, but simultaneously made evident several problems. - - ------------------------ --------------------------------- -------------------- - [Previous](67-05.html) [Table of Contents](index.html) [Next](68-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/68-02.md b/68-02.md index 72dec77..28c1815 100644 --- a/68-02.md +++ b/68-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](68-01.html) [Table of Contents](index.html) [Next](68-03.html) - ------------------------ --------------------------------- -------------------- - A primary problem with Gouraud shading is that it requires the vertices used for world geometry to serve as lighting sample points as well, even though there isn't necessarily a close relationship between lighting and @@ -137,11 +133,3 @@ polygons are added to support additional lighting detail as needed, and lighting values are calculated at the vertices of all polygons. At runtime, the lighting values are modified if dynamic lighting is required, and then the polygons are drawn with Gouraud shading. - - ------------------------ --------------------------------- -------------------- - [Previous](68-01.html) [Table of Contents](index.html) [Next](68-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/68-03.md b/68-03.md index 589f08f..3f339cd 100644 --- a/68-03.md +++ b/68-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](68-02.html) [Table of Contents](index.html) [Next](68-04.html) - ------------------------ --------------------------------- -------------------- - Quake's approach, which I'll call surface-based lighting, preprocesses differently, and adds an extra rendering step. During off-line preprocessing, a grid, called a light map, is calculated for each @@ -113,11 +109,3 @@ surface, the speed of the surface-caching approach is somewhat slower than Gouraud shading, but generally surface caching provides equal or better performance, so once surface caching was implemented in Quake, performance was no longer a problem—but size became a concern. - - ------------------------ --------------------------------- -------------------- - [Previous](68-02.html) [Table of Contents](index.html) [Next](68-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/68-04.md b/68-04.md index a7e1ac4..308a24b 100644 --- a/68-04.md +++ b/68-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](68-03.html) [Table of Contents](index.html) [Next](69-01.html) - ------------------------ --------------------------------- -------------------- - The amount of memory required for surface caching looked forbidding at first. Surfaces are large relative to texture tiles, because every texel of every surface is unique. Also, a surface can contain many texels @@ -84,11 +80,3 @@ Basically, the surface is a handy repository for all sorts of effects, because multiple techniques can be composited, because it caches the results for reuse without rebuilding, and because the texels constructed in a surface are automatically drawn in perspective. - - ------------------------ --------------------------------- -------------------- - [Previous](68-03.html) [Table of Contents](index.html) [Next](69-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/69-01.md b/69-01.md index 0bcd6f6..349121b 100644 --- a/69-01.md +++ b/69-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](68-04.html) [Table of Contents](index.html) [Next](69-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 69\ Surface Caching and Quake's Triangle Models {#Heading1} -------------------------------------------- @@ -127,11 +123,3 @@ work well, just not as relatively well compared to Gouraud shading as is the case in software. Second, there are at least two alternatives that preserve the advantages of surface caching without many of the disadvantages noted above. - - ------------------------ --------------------------------- -------------------- - [Previous](68-04.html) [Table of Contents](index.html) [Next](69-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/69-02.md b/69-02.md index a1fba8a..4a1f4ad 100644 --- a/69-02.md +++ b/69-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](69-01.html) [Table of Contents](index.html) [Next](69-03.html) - ------------------------ --------------------------------- -------------------- - #### Letting the Graphics Card Build the Textures {#Heading4} One obvious solution is to have the accelerator card build the textures, @@ -103,11 +99,3 @@ few exceptions, noted below. The entire world is drawn first, and then the triangle models are drawn, using z-buffering for proper visibility. For each triangle model, all vertices are transformed and projected first, and then each triangle is drawn separately. - - ------------------------ --------------------------------- -------------------- - [Previous](69-01.html) [Table of Contents](index.html) [Next](69-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/69-03.md b/69-03.md index b11d517..bfdc920 100644 --- a/69-03.md +++ b/69-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](69-02.html) [Table of Contents](index.html) [Next](69-04.html) - ------------------------ --------------------------------- -------------------- - Triangle models are stored quite differently from the world itself. Each model consists of front and back skins stretched around a triangle mesh, and contains a full set of vertex coordinates for each animation frame, @@ -121,11 +117,3 @@ First, all vertices in the model are drawn. Ideally, only the vertices on the visible side of the model would be drawn, but determining which vertices those are would take time, and the occasional error from a visible back vertex is lost in the noise. - - ------------------------ --------------------------------- -------------------- - [Previous](69-02.html) [Table of Contents](index.html) [Next](69-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/69-04.md b/69-04.md index 8d0f55d..6e15500 100644 --- a/69-04.md +++ b/69-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](69-03.html) [Table of Contents](index.html) [Next](70-01.html) - ------------------------ --------------------------------- -------------------- - Once the vertices are drawn, the triangles are processed one at a time. Each triangle that makes it through backface culling is then drawn with recursive subdivision. If any of the triangle's sides is more than one @@ -201,11 +197,3 @@ frustrating, but the truth is, it's these nearly infinite possibilities that make 3-D so interesting; not only is it an endless, varied challenge, but there's almost always a better solution waiting to be found. - - ------------------------ --------------------------------- -------------------- - [Previous](69-03.html) [Table of Contents](index.html) [Next](70-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/70-01.md b/70-01.md index 3f09274..50ac42b 100644 --- a/70-01.md +++ b/70-01.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](69-04.html) [Table of Contents](index.html) [Next](70-02.html) - ------------------------ --------------------------------- -------------------- - Chapter 70\ Quake: A Post-Mortem and a Glimpse into the Future {#Heading1} --------------------------------------------------- @@ -119,11 +115,3 @@ splits, thus reducing the total number of polygons per level, not only shrinks Quake's memory footprint, but also reduces the number of polygons that need to be processed by the 3-D pipeline, producing a speedup of about 10% in Quake's overall performance. - - ------------------------ --------------------------------- -------------------- - [Previous](69-04.html) [Table of Contents](index.html) [Next](70-02.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/70-02.md b/70-02.md index 95c1068..f585564 100644 --- a/70-02.md +++ b/70-02.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](70-01.html) [Table of Contents](index.html) [Next](70-03.html) - ------------------------ --------------------------------- -------------------- - Getting proper front-to-back drawing order is a little more complicated with polygons on nodes. As we walk the BSP tree front-to-back, in each leaf we mark the polygons that are at least partially in that leaf, and @@ -103,11 +99,3 @@ map, a sampling of light values on a 16-texel grid. In Quake 2, radiosity lighting—a considerably more expensive process, but one that produces highly realistic lighting—is performed, but I'll save that for later. - - ------------------------ --------------------------------- -------------------- - [Previous](70-01.html) [Table of Contents](index.html) [Next](70-03.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/70-03.md b/70-03.md index 2327f00..c1947c3 100644 --- a/70-03.md +++ b/70-03.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](70-02.html) [Table of Contents](index.html) [Next](70-04.html) - ------------------------ --------------------------------- -------------------- - ### Passages: The Last-Minute Change that Didn't Happen {#Heading4} Earlier, I mentioned that we almost changed 3-D engines again in the @@ -115,11 +111,3 @@ constraints placed on design, the better. ------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ![](images/i.jpg) *A corollary is that best case performance can be seductively misleading; it's a great feeling to see a scene running at 30 or even 60 frames per second, but if the bulk of the game runs at 15 fps, those best cases are just going to make the rest of the game look worse.* ------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - ------------------------ --------------------------------- -------------------- - [Previous](70-02.html) [Table of Contents](index.html) [Next](70-04.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/70-04.md b/70-04.md index 756d5ee..7dc1166 100644 --- a/70-04.md +++ b/70-04.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](70-03.html) [Table of Contents](index.html) [Next](70-05.html) - ------------------------ --------------------------------- -------------------- - The edge list is an atypical technology for John; it's an extra stage in the engine, it's complex, and it doesn't scale well. A Quake level might have a maximum of 500 potentially drawable polygons that get placed into @@ -125,11 +121,3 @@ rasterizer is both subpixel and subtexel correct, Quake worlds are visually very solid and stable. This was an important design goal from the start, both as a point of technical pride and because it greatly improves the player's sense of immersion. - - ------------------------ --------------------------------- -------------------- - [Previous](70-03.html) [Table of Contents](index.html) [Next](70-05.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/70-05.md b/70-05.md index 07af191..24c196e 100644 --- a/70-05.md +++ b/70-05.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](70-04.html) [Table of Contents](index.html) [Next](70-06.html) - ------------------------ --------------------------------- -------------------- - ### Entities {#Heading9} So far, all we've drawn is the static, unchanging (apart from dynamic @@ -124,11 +120,3 @@ the view pyramid, and to identify those that were unclipped, so they could be sent through a special fast path. The biggest breakthrough, though, was a very different sort of rasterizer that John came up with for relatively distant models. - - ------------------------ --------------------------------- -------------------- - [Previous](70-04.html) [Table of Contents](index.html) [Next](70-06.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/70-06.md b/70-06.md index d1c60be..f31b134 100644 --- a/70-06.md +++ b/70-06.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](70-05.html) [Table of Contents](index.html) [Next](70-07.html) - ------------------------ --------------------------------- -------------------- - #### The Subdivision Rasterizer {#Heading12} This rasterizer, which we call the *subdivision rasterizer*, first draws @@ -128,11 +124,3 @@ alpha lighting for hardware accelerators depends on a game's needs, and it seems most likely that the two approaches will be mixed together, with surface caching used for special surfaces, and two-pass alpha lighting used for most drawing. - - ------------------------ --------------------------------- -------------------- - [Previous](70-05.html) [Table of Contents](index.html) [Next](70-07.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/70-07.md b/70-07.md index ea48bd2..8a2a74c 100644 --- a/70-07.md +++ b/70-07.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](70-06.html) [Table of Contents](index.html) [Next](70-08.html) - ------------------------ --------------------------------- -------------------- - #### GLQuake {#Heading17} The second (and, according to current plans, last) port of Quake to a @@ -125,11 +121,3 @@ improve the multiplayer experience, especially for people linked by modem, by reducing actual and perceived latency. Before I discuss QuakeWorld, however, I should discuss the evolution of Quake's multiplayer code. - - ------------------------ --------------------------------- -------------------- - [Previous](70-06.html) [Table of Contents](index.html) [Next](70-08.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/70-08.md b/70-08.md index e2649d0..ce4f477 100644 --- a/70-08.md +++ b/70-08.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](70-07.html) [Table of Contents](index.html) [Next](70-09.html) - ------------------------ --------------------------------- -------------------- - From the beginning, Quake was conceived as a client-server app, specifically so that it would be possible to have persistent servers always running on the Internet, independent of whether anyone was @@ -117,11 +113,3 @@ O(polygons^2^), but with the PVS it's O(polygons\*average\_potentially\_visible\_polygons), which is over an order of magnitude less (and increases approximately linearly, rather than as a squared function, with greater-level complexity). - - ------------------------ --------------------------------- -------------------- - [Previous](70-07.html) [Table of Contents](index.html) [Next](70-09.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/70-09.md b/70-09.md index b20f43a..428aed1 100644 --- a/70-09.md +++ b/70-09.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- ------------------------- - [Previous](70-08.html) [Table of Contents](index.html) [Next](appendix-a.html) - ------------------------ --------------------------------- ------------------------- - Also, the moving sky texture will probably be gone or will change. One likely replacement is an enclosing texture-mapped box around the world, at a virtually infinite distance; this will allow open vistas, much like @@ -114,11 +110,3 @@ rut of established techniques, you must constantly strive to "do better with less, in a different way"; keep learning and changing and trying new approaches—and working your rear end off—and odds are you'll be part of the wave of the future. - - ------------------------ --------------------------------- ------------------------- - [Previous](70-08.html) [Table of Contents](index.html) [Next](appendix-a.html) - ------------------------ --------------------------------- ------------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/about.md b/about.md index 620e4b6..e8ccf74 100644 --- a/about.md +++ b/about.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- --------------------------- - [Previous](intro.html) [Table of Contents](index.html) [Next](about_author.html) - ------------------------ --------------------------------- --------------------------- - Foreword {#Heading1} -------- @@ -92,11 +88,3 @@ articles can provide similar stepping stones for others. —*John Carmack*\ id Software - - ------------------------ --------------------------------- --------------------------- - [Previous](intro.html) [Table of Contents](index.html) [Next](about_author.html) - ------------------------ --------------------------------- --------------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/about_author.md b/about_author.md index faa0fe8..f997f1a 100644 --- a/about_author.md +++ b/about_author.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](about.html) [Table of Contents](index.html) [Next](01-01.html) - ------------------------ --------------------------------- -------------------- - Acknowledgments {#Heading1} --------------- @@ -42,11 +38,3 @@ contributors by name in this book, but if your name is omitted, my apologies, and consider yourself thanked; this book could not have happened without you. And, of course, thanks to Shay and Emily for their generous patience with my passion for writing and computers. - - ------------------------ --------------------------------- -------------------- - [Previous](about.html) [Table of Contents](index.html) [Next](01-01.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/appendix-a.md b/appendix-a.md index 411fda3..0e347f4 100644 --- a/appendix-a.md +++ b/appendix-a.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- ------------------------- - [Previous](70-09.html) [Table of Contents](index.html) [Next](book-index.html) - ------------------------ --------------------------------- ------------------------- - Afterword {#Heading1} --------- @@ -85,11 +81,3 @@ some unexpected success, that not half of the things we call impossible have any right at all to wear the label. —Michael Abrash - - ------------------------ --------------------------------- ------------------------- - [Previous](70-09.html) [Table of Contents](index.html) [Next](book-index.html) - ------------------------ --------------------------------- ------------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/book-index.md b/book-index.md index 4b7724d..e0cf16e 100644 --- a/book-index.md +++ b/book-index.md @@ -1,7 +1,3 @@ - ----------------------------- --------------------------------- -------------------- - [Previous](appendix-a.html) [Table of Contents](index.html) [Next](index.html) - ----------------------------- --------------------------------- -------------------- - Index {#Heading1} ----- @@ -7060,11 +7056,3 @@ Zen timer, **37-38**, 43 long-period Zen timer, **63-65** Zen timer, **41-42**, 47-48 - - ----------------------------- --------------------------------- -------------------- - [Previous](appendix-a.html) [Table of Contents](index.html) [Next](index.html) - ----------------------------- --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/index.md b/index.md index 9bdc02e..1a3d764 100644 --- a/index.md +++ b/index.md @@ -1,8 +1,6 @@ Michael Abrash's Graphics Programming Black Book Special Edition ---------------------------------------------------------------- -* * * * * - 1. [Introduction](intro.html) 2. [Foreword](about.html) 3. [About the Author](about_author.html) @@ -893,7 +891,3 @@ Michael Abrash's Graphics Programming Black Book Special Edition 6. [Appendix A](appendix-a.html) 7. [Index](book-index.html) - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash diff --git a/intro.md b/intro.md index 9fc5871..f46c8b9 100644 --- a/intro.md +++ b/intro.md @@ -1,7 +1,3 @@ - ------------------------ --------------------------------- -------------------- - [Previous](index.html) [Table of Contents](index.html) [Next](about.html) - ------------------------ --------------------------------- -------------------- - Introduction {#Heading1} ------------ @@ -81,11 +77,3 @@ And the next decade is shaping up to be just as exciting! —*Michael Abrash*\ Bellevue, Washington\ May 1997 - - ------------------------ --------------------------------- -------------------- - [Previous](index.html) [Table of Contents](index.html) [Next](about.html) - ------------------------ --------------------------------- -------------------- - -* * * * * - -Graphics Programming Black Book © 2001 Michael Abrash