Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
124
34-01.md
Normal file
124
34-01.md
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[Previous](33-04.html) [Table of Contents](index.html) [Next](34-02.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
Chapter 34\
|
||||
Changing Colors without Writing Pixels {#Heading1}
|
||||
---------------------------------------
|
||||
|
||||
### Special Effects through Realtime Manipulation of DAC Colors {#Heading2}
|
||||
|
||||
Sometimes, strange as it may seem, the harder you try, the less you
|
||||
accomplish. Brute force is fine when it suffices, but it does not always
|
||||
suffice, and when it does not, finesse and alternative approaches are
|
||||
called for. Such is the case with rapidly cycling through colors by
|
||||
repeatedly loading the VGA’s Digital to Analog Converter (DAC). No
|
||||
matter how much you optimize your code, you just can’t reliably load the
|
||||
whole DAC cleanly in a single frame, so you had best find other ways to
|
||||
use the DAC to cycle colors. What’s more, BIOS support for DAC loading
|
||||
is so inconsistent that it’s unusable for color cycling; direct loading
|
||||
through the I/O ports is the only way to go. We’ll see why next, as we
|
||||
explore color cycling, and then finish up this chapter and this section
|
||||
by cleaning up some odds and ends about VGA color.
|
||||
|
||||
There’s a lot to be said about loading the DAC, so let’s dive right in
|
||||
and see where the complications lie.
|
||||
|
||||
### Color Cycling {#Heading3}
|
||||
|
||||
As we’ve learned in past chapters, the VGA’s DAC contains 256 storage
|
||||
locations, each holding one 18-bit value representing an RGB color
|
||||
triplet organized as 6 bits per primary color. Each and every pixel
|
||||
generated by the VGA is fed into the DAC as an 8-bit value (refer to
|
||||
Chapter 33 and to Chapter A on the companion CD-ROM to see how pixels
|
||||
become 8-bit values in non-256 color modes) and each 8-bit value is used
|
||||
to look up one of the 256 values stored in the DAC. The looked-up value
|
||||
is then converted to analog red, green, and blue signals and sent to the
|
||||
monitor to form one pixel.
|
||||
|
||||
That’s straightforward enough, and we’ve produced some pretty impressive
|
||||
color effects by loading the DAC once and then playing with the 8-bit
|
||||
path into the DAC. Now, however, we want to generate color effects by
|
||||
dynamically changing the values stored in the DAC in real time, a
|
||||
technique that I’ll call *color cycling*. The potential of color cycling
|
||||
should be obvious: Smooth motion can easily be simulated by altering the
|
||||
colors in an appropriate pattern, and all sorts of changing color
|
||||
effects can be produced without altering a single bit of display memory.
|
||||
|
||||
For example, a sunset can be made to color and darken by altering the
|
||||
DAC locations containing the colors used to draw the sunset, or a river
|
||||
can be made to appear to flow by cycling through the colors used to draw
|
||||
the river. Another use for color cycling is in providing more realistic
|
||||
displays for applications like realtime 3-D games, where the VGA’s 256
|
||||
simultaneous colors can be made to seem like many more by changing the
|
||||
DAC settings from frame to frame to match the changing color demands of
|
||||
the rendered scene. Which leaves only one question: How do we load the
|
||||
DAC smoothly in realtime?
|
||||
|
||||
Actually, so far as I know, you can’t. At least you can’t load the
|
||||
*entire* DAC—all 256 locations—frame after frame without producing
|
||||
distressing on-screen effects on at least some computers. In non-256
|
||||
color modes, it is indeed possible to load the DAC quickly enough to
|
||||
cycle all displayed colors (of which there are 16 or fewer), so color
|
||||
cycling could be used successfully to cycle all colors in such modes. On
|
||||
the other hand, color paging (which flips among a number of color sets
|
||||
stored within the DAC in all modes other than 256 color mode, as
|
||||
discussed in Chapter A on the companion CD-ROM) can be used in non-256
|
||||
color modes to produce many of the same effects as color cycling and is
|
||||
considerably simpler and more reliable then color cycling, so color
|
||||
paging is generally superior to color cycling whenever it’s available.
|
||||
In short, color cycling is really the method of choice for dynamic color
|
||||
effects only in 256-color mode—but, regrettably, color cycling is at its
|
||||
least reliable and capable in that mode, as we’ll see next.
|
||||
|
||||
### The Heart of the Problem {#Heading4}
|
||||
|
||||
Here’s the problem with loading the entire DAC repeatedly: The DAC
|
||||
contains 256 color storage locations, each loaded via either 3 or 4
|
||||
**OUT** instructions (more on that next), so at least 768 **OUT**s are
|
||||
needed to load the entire DAC. That many **OUT**s take a considerable
|
||||
amount of time, all the more so because **OUT**s are painfully slow on
|
||||
486s and Pentiums, and because the DAC is frequently on the ISA bus
|
||||
(although VLB and PCI are increasingly common), where wait states are
|
||||
inserted in fast computers. In an 8 MHz AT, 768 **OUT**s alone would
|
||||
take 288 microseconds, and the data loading and looping that are also
|
||||
required would take in the ballpark of 1,800 microseconds more, for a
|
||||
minimum of 2 milliseconds total.
|
||||
|
||||
As it happens, the DAC should only be loaded during vertical blanking;
|
||||
that is, the time between the end of displaying the bottom border and
|
||||
the start of displaying the top border, when no video information at all
|
||||
is being sent to the screen by the DAC. Otherwise, small dots of snow
|
||||
appear on the screen, and while an occasional dot of this sort wouldn’t
|
||||
be a problem, the constant DAC loading required by color cycling would
|
||||
produce a veritable snowstorm on the screen. By the way, I do mean
|
||||
“border,” not “frame buffer”; the overscan pixels pass through the DAC
|
||||
just like the pixels controlled by the frame buffer, so you can’t even
|
||||
load the DAC while the border color is being displayed without getting
|
||||
snow.
|
||||
|
||||
The start of vertical blanking itself is not easy to find, but the
|
||||
leading edge of the vertical sync pulse is easy to detect via bit 3 of
|
||||
the Input Status 1 register at 3DAH; when bit 3 is 1, the vertical sync
|
||||
pulse is active. Conveniently, the vertical sync pulse starts partway
|
||||
through but not too far into vertical blanking, so it serves as a handy
|
||||
way to tell when it’s safe to load the DAC without producing snow on the
|
||||
screen.
|
||||
|
||||
So we wait for the start of the vertical sync pulse, then begin to load
|
||||
the DAC. There’s a catch, though. On many computers—Pentiums, 486s, and
|
||||
386s sometimes, 286s most of the time, and 8088s all the time—there just
|
||||
isn’t enough time between the start of the vertical sync pulse and the
|
||||
end of vertical blanking to load all 256 DAC locations. That’s the crux
|
||||
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
|
||||
Loading…
Reference in a new issue