Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
237
39-02.md
Normal file
237
39-02.md
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[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,
|
||||
Listing 39.1 increases pure drawing speed (disregarding edge tracing and
|
||||
other nondrawing time) by more than an order of magnitude over Chapter
|
||||
38’s draw-pixel-based code, despite the fact that Listing 39.1 requires
|
||||
a large (in this case, the Compact) data model. Listing 39.1 works fine
|
||||
with Borland C++, but may not work with other compilers, for it relies
|
||||
on the aforementioned interaction between memset and the selected memory
|
||||
model.
|
||||
|
||||
* * * * *
|
||||
|
||||
Implementation
|
||||
|
||||
Total Polygon\
|
||||
Filling Time
|
||||
|
||||
DrawHorizontal\
|
||||
LineList
|
||||
|
||||
ScanEdge
|
||||
|
||||
FillConvex\
|
||||
Polygon
|
||||
|
||||
* * * * *
|
||||
|
||||
Drawing to display memory in mode 13h
|
||||
|
||||
C floating point scan/DrawPixel drawing code from Chapter 38, (small
|
||||
model)
|
||||
|
||||
11.69
|
||||
|
||||
5.80 seconds\
|
||||
(50% of total)
|
||||
|
||||
5.86\
|
||||
(50%)
|
||||
|
||||
0.03\
|
||||
(\<1%)
|
||||
|
||||
C floating point scan/memset drawing (Listing 39.1, compact model)
|
||||
|
||||
6.64
|
||||
|
||||
0.49\
|
||||
(7%)
|
||||
|
||||
6.11\
|
||||
(92%)
|
||||
|
||||
0.04\
|
||||
(\<1%)
|
||||
|
||||
C integer scan/memset drawing (Listing 39.1 & Listing 39.2, compact
|
||||
model)
|
||||
|
||||
0.60
|
||||
|
||||
0.49\
|
||||
(82%)
|
||||
|
||||
0.07\
|
||||
(12%)
|
||||
|
||||
0.04\
|
||||
(7%)
|
||||
|
||||
C integer scan/ASM drawing (Listing 39.2 & Listing 39.3, small model)
|
||||
|
||||
0.45
|
||||
|
||||
0.36\
|
||||
(80%)
|
||||
|
||||
0.06\
|
||||
(13%)
|
||||
|
||||
0.03\
|
||||
(7%)
|
||||
|
||||
ASM integer scan/ASM drawing (Listing 40.3 & Listing 40.4,small model)
|
||||
|
||||
0.42
|
||||
|
||||
0.36\
|
||||
(86%)
|
||||
|
||||
0.03\
|
||||
(7%)
|
||||
|
||||
0.03\
|
||||
(7%)
|
||||
|
||||
Drawing to system memory
|
||||
|
||||
C integer scan/memset drawing (Listing 39.1 & Listing 39.2,compact
|
||||
model)
|
||||
|
||||
0.31
|
||||
|
||||
0.20\
|
||||
(65%)
|
||||
|
||||
0.07\
|
||||
(23%)
|
||||
|
||||
0.04\
|
||||
(13%)
|
||||
|
||||
ASM integer scan/ASM drawing (Listing 39.3 & Listing 39.4,small model)
|
||||
|
||||
0.13
|
||||
|
||||
0.07\
|
||||
(54%)
|
||||
|
||||
0.03\
|
||||
(23%)
|
||||
|
||||
0.03\
|
||||
(23%)
|
||||
|
||||
All times are in seconds, as measured with Turbo Profiler on a 20-MHz
|
||||
cached 386 with no math coprocessor installed. Note that time spent in
|
||||
**main()** is not included. C code was compiled with Borland C++ with
|
||||
maximum optimization (-G -O -Z -r -a); assembly language code was
|
||||
assembled with TASM. Percentages of combined times are rounded to the
|
||||
nearest percent, so the sum of the three percentages does not always
|
||||
equal 100.
|
||||
|
||||
* * * * *
|
||||
|
||||
Table 39.1 Polygon fill performance.
|
||||
|
||||
* * * * *
|
||||
|
||||
**LISTING 39.1 L39-1.C**
|
||||
|
||||
/* Draws all pixels in the list of horizontal lines passed in, in
|
||||
mode 13h, the VGA’s 320x200 256-color mode. Uses memset to fill
|
||||
each line, which is much faster than using DrawPixel but requires
|
||||
that a large data model (compact, large, or huge) be in use when
|
||||
running in real mode or 286 protected mode.
|
||||
All C code tested with Borland C++. */
|
||||
|
||||
#include <string.h>
|
||||
#include <dos.h>
|
||||
#include “polygon.h”
|
||||
|
||||
#define SCREEN_WIDTH 320
|
||||
#define SCREEN_SEGMENT 0xA000
|
||||
|
||||
void DrawHorizontalLineList(struct HLineList * HLineListPtr,
|
||||
int Color)
|
||||
{
|
||||
struct HLine *HLinePtr;
|
||||
int Length, Width;
|
||||
unsigned char far *ScreenPtr;
|
||||
|
||||
/* Point to the start of the first scan line on which to draw */
|
||||
ScreenPtr = MK_FP(SCREEN_SEGMENT,
|
||||
HLineListPtr->YStart * SCREEN_WIDTH);
|
||||
|
||||
/* Point to the XStart/XEnd descriptor for the first (top)
|
||||
horizontal line */
|
||||
HLinePtr = HLineListPtr->HLinePtr;
|
||||
/* Draw each horizontal line in turn, starting with the top one and
|
||||
advancing one line each time */
|
||||
Length = HLineListPtr->Length;
|
||||
while (Length-- > 0) {
|
||||
/* Draw the whole horizontal line if it has a positive width */
|
||||
if ((Width = HLinePtr->XEnd - HLinePtr->XStart + 1) > 0)
|
||||
memset(ScreenPtr + HLinePtr->XStart, Color, Width);
|
||||
HLinePtr++; /* point to next scan line X info */
|
||||
ScreenPtr += SCREEN_WIDTH; /* point to next scan line start */
|
||||
}
|
||||
}
|
||||
|
||||
At this point, I’d like to mention that benchmarks are notoriously
|
||||
unreliable; the results in Table 39.1 are accurate *only* for the test
|
||||
program, and only when running on a particular system. Results could be
|
||||
vastly different if smaller, larger, or more complex polygons were
|
||||
drawn, or if a faster or slower computer/VGA combination were used.
|
||||
These factors notwithstanding, the test program does fill a variety of
|
||||
polygons of varying complexity sized from large to small and in between,
|
||||
and certainly the order of magnitude difference between Listing 39.1 and
|
||||
the old version of **DrawHorizontalLineList** is a clear indication of
|
||||
which code is superior.
|
||||
|
||||
Anyway, Listing 39.1 has the desired effect of vastly improving drawing
|
||||
time. There are cycles yet to be had in the drawing code, but as tracing
|
||||
polygon edges now takes 92 percent of the polygon filling time, it’s
|
||||
logical to optimize the tracing code next.
|
||||
|
||||
#### Fast Edge Tracing {#Heading5}
|
||||
|
||||
There’s no secret as to why last chapter’s **ScanEdge** was so slow: It
|
||||
used floating point calculations. One secret of fast graphics is using
|
||||
integer or fixed-point calculations, instead. (Sure, the floating point
|
||||
code would run faster if a math coprocessor were installed, but it would
|
||||
still be slower than the alternatives; besides, why require a math
|
||||
coprocessor when you don’t have to?) Both integer and fixed-point
|
||||
calculations are fast. In many cases, fixed-point is faster, but integer
|
||||
calculations have one tremendous virtue: They’re completely accurate.
|
||||
The tiny imprecision inherent in either fixed or floating-point
|
||||
calculations can result in occasional pixels being one position off from
|
||||
their proper location. This is no great tragedy, but after going to so
|
||||
much trouble to ensure that polygons don’t overlap at common edges, why
|
||||
not get it exactly right?
|
||||
|
||||
In fact, when I tested out the integer edge tracing code by comparing an
|
||||
integer-based test image to one produced by floating-point calculations,
|
||||
two pixels out of the whole screen differed, leading me to suspect a bug
|
||||
in the integer code. It turned out, however, that’s in those two cases,
|
||||
the floating point results were sufficiently imprecise to creep from
|
||||
just under an integer value to just over it, so that the **ceil**
|
||||
function returned a coordinate that was one too large.
|
||||
|
||||
------------------- ---------------------------------------------------------------------------------------------------------
|
||||
 *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
|
||||
Loading…
Reference in a new issue