Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
84
35-06.md
Normal file
84
35-06.md
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[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
|
||||
VGA isn’t trivial (as we’ve seen in the early chapters of this part).
|
||||
Besides, while the explanation of **EVGADot** is lengthy, the code
|
||||
itself is only five lines long.
|
||||
|
||||
Line drawing would be somewhat faster if the code of **EVGADot** were
|
||||
made an inline part of **Octant0** and **Octant1**, thereby saving the
|
||||
overhead of preparing parameters and calling the function. Feel free to
|
||||
do this if you wish; I maintained **EVGADot** as a separate function for
|
||||
clarity and for ease of inserting a pixel-drawing function for a
|
||||
different graphics adapter, should that be desired. If you do install a
|
||||
pixel-drawing function for a different adapter, or a fundamentally
|
||||
different mode such as a 256-color SuperVGA mode, remember to remove the
|
||||
hardware-dependent **outportb** lines in **EVGALine** itself.
|
||||
|
||||
### Comments on the C Implementation {#Heading10}
|
||||
|
||||
**EVGALine** does no error checking whatsoever. My assumption in writing
|
||||
**EVGALine** was that it would be ultimately used as the lowest-level
|
||||
primitive of a graphics software package, with operations such as error
|
||||
checking and clipping performed at a higher level. Similarly,
|
||||
**EVGALine** is tied to the VGA’s screen coordinate system of (0,0) to
|
||||
(639,199) (in mode 0EH), (0,0) to (639,349) (in modes 0FH and 10H), or
|
||||
(0,0) to (639,479) (in mode 12H), with the upper left corner considered
|
||||
to be (0,0). Again, transformation from any coordinate system to the
|
||||
coordinate system used by **EVGALine** can be performed at a higher
|
||||
level. **EVGALine** is specifically designed to do one thing: draw lines
|
||||
into the display memory of the VGA. Additional functionality can be
|
||||
supplied by the code that calls **EVGALine**.
|
||||
|
||||
The version of **EVGALine** shown in Listing 35.1 is reasonably fast,
|
||||
but it is not as fast as it might be. Inclusion of **EVGADot** directly
|
||||
into **Octant0** and **Octant1**, and, indeed, inclusion of **Octant0**
|
||||
and **Octant1** directly into **EVGALine** would speed execution by
|
||||
saving the overhead of calling and parameter passing. Handpicked
|
||||
register variables might speed performance as well, as would the use of
|
||||
word **OUT**s rather than byte **OUT**s. A more significant performance
|
||||
increase would come from eliminating separate calculation of the address
|
||||
and mask for each pixel. Since the location of each pixel relative to
|
||||
the previous pixel is known, the address and mask could simply be
|
||||
adjusted from one pixel to the next, rather than recalculated from
|
||||
scratch.
|
||||
|
||||
These enhancements are not incorporated into the code in Listing 35.1
|
||||
for a couple of reasons. One reason is that it’s important that the
|
||||
workings of the algorithm be clearly visible in the code, for learning
|
||||
purposes. Once the implementation is understood, rewriting it for
|
||||
improved performance would certainly be a worthwhile exercise. Another
|
||||
reason is that when flat-out speed is needed, assembly language is the
|
||||
best way to go. Why produce hard-to-understand C code to boost speed a
|
||||
bit when assembly-language code can perform the same task at two or more
|
||||
times the speed?
|
||||
|
||||
Given which, a high-speed assembly language version of **EVGALine**
|
||||
would seem to be a logical next step.
|
||||
|
||||
### Bresenham’s Algorithm in Assembly {#Heading11}
|
||||
|
||||
Listing 35.3 is a high-performance implementation of Bresenham’s
|
||||
algorithm, written entirely in assembly language. The code is callable
|
||||
from C just as is Listing 35.1, with the same name, **EVGALine**, and
|
||||
with the same parameters. Either of the two can be linked to any program
|
||||
that calls **EVGALine**, since they appear to be identical to the
|
||||
calling program. The only difference between the two versions is that
|
||||
the sample program in Listing 35.2 runs over three times as fast on a
|
||||
486 with an ISA-bus VGA when calling the assembly-language version of
|
||||
**EVGALine** as when calling the C version, and the difference would be
|
||||
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
|
||||
Loading…
Reference in a new issue