Move everything into one directory, update links
This commit is contained in:
parent
b946ff9e70
commit
4eef8b2919
680 changed files with 1638 additions and 1638 deletions
182
42-04.html
Normal file
182
42-04.html
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<META name=vsisbn content="1576101746">
|
||||
<META name=vstitle content="Michael Abrash's Graphics Programming Black Book, Special Edition">
|
||||
<META name=vsauthor content="Michael Abrash">
|
||||
<META name=vspublisher content="The Coriolis Group">
|
||||
<META name=vspubdate content="07/01/97">
|
||||
<META name=vscategory content="Web and Software Development: Game Development,Web and Software Development: Graphics and Multimedia Development">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<TITLE>Michael Abrash's Graphics Programming Black Book Special Edition: Wu'ed in Haste; Fried, Stewed at Leisure</TITLE>
|
||||
|
||||
<!-- HEADER -->
|
||||
<!-- Empty Reference Subhead -->
|
||||
|
||||
<!--ISBN=1576101746//-->
|
||||
<!--TITLE=Michael Abrash's Graphics Programming Black Book Special Edition//-->
|
||||
<!--AUTHOR=Michael Abrash//-->
|
||||
<!--PUBLISHER=The Coriolis Group, Inc.//-->
|
||||
<!--CHAPTER=42//-->
|
||||
<!--PAGES=784-787//-->
|
||||
<!--UNASSIGNED1//-->
|
||||
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
|
||||
|
||||
<CENTER>
|
||||
<TABLE BORDER>
|
||||
<TR>
|
||||
<TD><A HREF="42-03.html">Previous</A></TD>
|
||||
<TD><A HREF="index.html">Table of Contents</A></TD>
|
||||
<TD><A HREF="42-05.html">Next</A></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</CENTER>
|
||||
<P><BR></P>
|
||||
<P><B>LISTING 42.4 L42-4.C</B></P>
|
||||
<!-- CODE //-->
|
||||
<PRE>
|
||||
/* Function to draw a non-antialiased line from (X0,Y0) to (X1,Y1), using a
|
||||
* simple fixed-point error accumulation approach.
|
||||
* Tested with Borland C++ in C compilation mode and the small model.
|
||||
*/
|
||||
extern void DrawPixel(int, int, int);
|
||||
|
||||
/* Non-antialiased line drawer.
|
||||
* (X0,Y0),(X1,Y1) = line to draw, Color = color in which to draw
|
||||
*/
|
||||
void DrawLine(int X0, int Y0, int X1, int Y1, int Color)
|
||||
{
|
||||
unsigned long ErrorAcc, ErrorAdj;
|
||||
int DeltaX, DeltaY, XDir, Temp;
|
||||
|
||||
/* Make sure the line runs top to bottom */
|
||||
if (Y0 > Y1) {
|
||||
Temp = Y0; Y0 = Y1; Y1 = Temp;
|
||||
Temp = X0; X0 = X1; X1 = Temp;
|
||||
}
|
||||
DrawPixel(X0, Y0, Color); /* draw the initial pixel */
|
||||
if ((DeltaX = X1 - X0) >= 0) {
|
||||
XDir = 1;
|
||||
} else {
|
||||
XDir = -1;
|
||||
DeltaX = -DeltaX; /* make DeltaX positive */
|
||||
}
|
||||
if ((DeltaY = Y1 - Y0) == 0) /* done if only one point in the line */
|
||||
if (DeltaX == 0) return;
|
||||
|
||||
ErrorAcc = 0x8000; /* initialize line error accumulator to .5, so we can
|
||||
advance when we get halfway to the next pixel */
|
||||
/* Is this an X-major or Y-major line? */
|
||||
if (DeltaY > DeltaX) {
|
||||
/* Y-major line; calculate 16-bit fixed-point fractional part of a
|
||||
pixel that X advances each time Y advances 1 pixel */
|
||||
ErrorAdj = ((((unsigned long)DeltaX << 17) / (unsigned long)DeltaY) +
|
||||
1) >> 1;
|
||||
/* Draw all pixels between the first and last */
|
||||
do {
|
||||
ErrorAcc += ErrorAdj; /* calculate error for this pixel */
|
||||
if (ErrorAcc & ~0xFFFFL) {
|
||||
/* The error accumulator turned over, so advance the X coord */
|
||||
X0 += XDir;
|
||||
ErrorAcc &= 0xFFFFL; /* clear integer part of result */
|
||||
}
|
||||
Y0++; /* Y-major, so always advance Y */
|
||||
DrawPixel(X0, Y0, Color);
|
||||
} while (--DeltaY);
|
||||
return;
|
||||
}
|
||||
/* It's an X-major line; calculate 16-bit fixed-point fractional part of a
|
||||
pixel that Y advances each time X advances 1 pixel */
|
||||
ErrorAdj = ((((unsigned long)DeltaY << 17) / (unsigned long)DeltaX) +
|
||||
1) >> 1;
|
||||
/* Draw all remaining pixels */
|
||||
do {
|
||||
ErrorAcc += ErrorAdj; /* calculate error for this pixel */
|
||||
if (ErrorAcc & ~0xFFFFL) {
|
||||
/* The error accumulator turned over, so advance the Y coord */
|
||||
Y0++;
|
||||
ErrorAcc &= 0xFFFFL; /* clear integer part of result */
|
||||
}
|
||||
X0 += XDir; /* X-major, so always advance X */
|
||||
DrawPixel(X0, Y0, Color);
|
||||
} while (--DeltaX);
|
||||
}
|
||||
</PRE>
|
||||
<!-- END CODE //-->
|
||||
<P>Listing 42.1 isn’t particularly fast, because it calls <B>DrawPixel()</B> for each pixel. On the other hand, <B>DrawPixel()</B> makes it easy to try out Wu antialiasing in a variety of modes; just adapt the code in Listing 42.3 for the 256-color mode you want to support. For example, Listing 42.5 shows code to draw Wu-antialiased lines in 640×480 256-color mode on SuperVGAs built around the Tseng Labs ET4000 chip with at least 512K of display memory installed. It’s well worth checking out Wu antialiasing at 640×480. Although antialiased lines look much smoother than normal lines at 320×200 resolution, they’re far from perfect, because the pixels are so big that the eye can’t blend them properly. At 640×480, however, Wu-antialiased lines look fabulous; from a couple of feet away, they look as straight and smooth as if they were drawn with a ruler.</P>
|
||||
<P><B>LISTING 42.5 L42-5.C</B></P>
|
||||
<!-- CODE //-->
|
||||
<PRE>
|
||||
/* Mode set and pixel-drawing functions for the 640x480 256-color mode of
|
||||
* Tseng Labs ET4000-based SuperVGAs.
|
||||
* Tested with Borland C++ in C compilation mode and the small model.
|
||||
*/
|
||||
#include <dos.h>
|
||||
|
||||
/* Screen dimension globals, used in main program to scale */
|
||||
int ScreenWidthInPixels = 640;
|
||||
int ScreenHeightInPixels = 480;
|
||||
|
||||
/* ET4000 640x480 256-color draw pixel function. */
|
||||
void DrawPixel(int X, int Y, int Color)
|
||||
{
|
||||
#define SCREEN_SEGMENT 0xA000
|
||||
#define GC_SEGMENT_SELECT 0x3CD /* ET4000 segment (bank) select reg */
|
||||
unsigned char far *ScreenPtr;
|
||||
unsigned int Bank;
|
||||
unsigned long BitmapAddress;
|
||||
|
||||
/* full bitmap address of pixel, as measured from address 0 to 0xFFFFF */
|
||||
BitmapAddress = (unsigned long) Y * ScreenWidthInPixels + X;
|
||||
/* Bank # is upper word of bitmap addr */
|
||||
Bank = BitmapAddress >> 16;
|
||||
/* Upper nibble is read bank #, lower nibble is write bank # */
|
||||
outp(GC_SEGMENT_SELECT, (Bank << 4) | Bank);
|
||||
/* Draw into the bank */
|
||||
FP_SEG(ScreenPtr) = SCREEN_SEGMENT;
|
||||
FP_OFF(ScreenPtr) = (unsigned int) BitmapAddress;
|
||||
*ScreenPtr = Color;
|
||||
}
|
||||
|
||||
/* ET4000 640x480 256-color mode-set function. */
|
||||
void SetMode()
|
||||
{
|
||||
union REGS regset;
|
||||
|
||||
/* Set to 640x480 256-color graphics mode */
|
||||
regset.x.ax = 0x002E;
|
||||
int86(0x10, &regset, &regset);
|
||||
}
|
||||
</PRE>
|
||||
<!-- END CODE //-->
|
||||
<P>Listing 42.1 requires that the DAC palette be set up so that a <B>NumLevel</B>-long block of palette entries contains linearly decreasing intensities of the drawing color. The size of the block is programmable, but must be a power of two. The more intensity levels, the better. Wu says that 32 intensities are enough; on my system, eight and even four levels looked pretty good. I found that gamma correction, which gives linearly spaced intensity steps, improved antialiasing quality significantly. Fortunately, we can program the palette with gamma-corrected values, so our drawing code doesn’t have to do any extra work.</P>
|
||||
<P>Listing 42.1 isn’t very fast, so I implemented Wu antialiasing in assembly, hard-coded for mode 13H. The implementation is shown in full 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!</P><P><BR></P>
|
||||
<CENTER>
|
||||
<TABLE BORDER>
|
||||
<TR>
|
||||
<TD><A HREF="42-03.html">Previous</A></TD>
|
||||
<TD><A HREF="index.html">Table of Contents</A></TD>
|
||||
<TD><A HREF="42-05.html">Next</A></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</CENTER>
|
||||
|
||||
<hr width="90%" size="1" noshade>
|
||||
<div align="center">
|
||||
<font face="Verdana,sans-serif" size="1">Graphics Programming Black Book © 2001 Michael Abrash</font>
|
||||
</div>
|
||||
<!-- all of the reference materials (books) have the footer and subfoot reveresed -->
|
||||
<!-- reference_subfoot = footer -->
|
||||
<!-- reference_footer = subfoot -->
|
||||
|
||||
<!-- BEGIN SUB FOOTER -->
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
<!-- END FOOTER -->
|
||||
|
||||
|
||||
Loading…
Reference in a new issue