_GRAPHICS PROGRAMMING COLUMN_ by Michael Abrash [LISTING ONE] /* Texture-map-draw the scan line between two edges. Uses approach of pre-stepping 1/2 pixel into the source image and rounding to the nearest source pixel at each step, so that texture maps will appear reasonably similar at all angles. */ void ScanOutLine(EdgeScan * LeftEdge, EdgeScan * RightEdge) { Fixedpoint SourceX; Fixedpoint SourceY; int DestX = LeftEdge->DestX; int DestXMax = RightEdge->DestX; Fixedpoint DestWidth; Fixedpoint SourceStepX, SourceStepY; /* Nothing to do if fully X clipped */ if ((DestXMax <= ClipMinX) || (DestX >= ClipMaxX)) { return; } if ((DestXMax - DestX) <= 0) { return; /* nothing to draw */ } SourceX = LeftEdge->SourceX; SourceY = LeftEdge->SourceY; /* Width of destination scan line, for scaling. Note: because this is an integer-based scaling, it can have a total error of as much as nearly one pixel. For more precise scaling, also maintain a fixed-point DestX in each edge, and use it for scaling. If this is done, it will also be necessary to nudge the source start coordinates to the right by an amount corresponding to the distance from the the real (fixed-point) DestX and the first pixel (at an integer X) to be drawn) */ DestWidth = INT_TO_FIXED(DestXMax - DestX); /* Calculate source steps that correspond to each dest X step (across the scan line) */ SourceStepX = FixedDiv(RightEdge->SourceX - SourceX, DestWidth); SourceStepY = FixedDiv(RightEdge->SourceY - SourceY, DestWidth); /* Advance 1/2 step in the stepping direction, to space scanned pixels evenly between the left and right edges. (There's a slight inaccuracy in dividing negative numbers by 2 by shifting rather than dividing, but the inaccuracy is in the least significant bit, and we'll just live with it.) */ SourceX += SourceStepX >> 1; SourceY += SourceStepY >> 1; /* Clip right edge if necssary */ if (DestXMax > ClipMaxX) DestXMax = ClipMaxX; /* Clip left edge if necssary */ if (DestX < ClipMinX) { SourceX += FixedMul(SourceStepX, INT_TO_FIXED(ClipMinX - DestX)); SourceY += FixedMul(SourceStepY, INT_TO_FIXED(ClipMinX - DestX)); DestX = ClipMinX; } /* Scan across the destination scan line, updating the source image position accordingly */ for (; DestX