This is for a single horizontal line of a polygon. This routine will
be getting called for each of the scanlines in a polygon, for every
polygon. Hmmm...I wonder how many times that startup code is gunna
get run through...
See all them parameters (I count 6)? That's just for a single piece
of a single polygon for a simple gouraud shader. What about a
bump-mapper and texture-mapper? Your stack will hate you for that,
you're driving it nuts! Push, Pop, Push, Pop, Push, Pop....
Here's a peek at your NEW and IMPROVED s-Buffer drawing routine. It
draws the ENTIRE screen:
void LowLevelDrawer( SBUFFER *Sbuf )
{ while( !Done ) { [do a little setup for this scanline] . . . [draw all segments for a single scanline (optimized code goes here)] . . . [next scanline] } [any exit code] . . . [return]
}
When you leave here, you have a new screen, drawn to completion, ready
for display.
One thing to note is that as you're drawing, if you watch it in slow-
motion, you'll see that you're drawing each scanline from
left-to-right, top-down. Nice and clean. I'll address this cool
if (New is entirely off-screen) return; // Make sure segment is sorted left-right
if (the list is empty) { just add it }
while(we still have entries in the list) { // Case 1 if (New.x1 > Cur.x2) { // Next Cur // Continue Checking } // Simply off-screen? (do this check again 'cause New is changin') else if (New.x1 >= ScreenResX || New.x2 < 0) { // Return } // Case 2 else if (New.x2 < Cur.x1) { // Add New before Cur; // Return } // Case 3 else if (New.x1 < Cur.x1) { // Split New at Cur's left-most point // Add New's left-half before Cur // Replace New with it's right half // Continue checking } // Case 4 else if (Cur.x1 < New.x1) { // Split Cur at New's left-most point // Add Cur's right-half after Cur // Next Cur // Continue checking } // Cases 5 & 6 else if (Cur.x2 > New.x2) { // Case 5 if (New.x1 == New.x2) { // If New's starting Z is behind Cur's starting Z, just return // Split Cur at New's right-most point + 1 // Replace Cur with it's right half // Add New before Cur // Return } else // Case 6 { // Split Cur at New's right-most point + 1 // Replace Cur with it's right half // Call IntersectSplit for New and Cur's left-half // Return } } // Cases 7 & 8 else if (Cur.x2 < New.x2 ) { // Case 7 if (Cur.x1 == Cur.x2) { // Split New at Cur's right-most point + 1 // If Cur is behind New's left-half, replace Cur with New's left-half // Continue checking using New's right half } // Case 8 else { // Split New at Cur's right-most point + 1 // Remove Cur from the list // Call IntersectSplit for Cur and New's left-half // Continue checking using New's right-half } } // Cases 9 & 10 else { // Case 9 if (Cur.x1 == Cur.x2) { // If Cur is behind New, replace Cur with New // Return } // Case 10 else { // Remove Cur from the list // Call IntersectSplit for Cur and New // Return } } }