Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

GSPAN.CPP

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  GSpan.cpp                                                                           */
00003 /*                                                                                      */
00004 /*  Author: John Pollard                                                                */
00005 /*  Description: Front to back span code                                                */
00006 /*                                                                                      */
00007 /*  The contents of this file are subject to the Genesis3D Public License               */
00008 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00009 /*  compliance with the License. You may obtain a copy of the License at                */
00010 /*  http://www.genesis3d.com                                                            */
00011 /*                                                                                      */
00012 /*  Software distributed under the License is distributed on an "AS IS"                 */
00013 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00014 /*  the License for the specific language governing rights and limitations              */
00015 /*  under the License.                                                                  */
00016 /*                                                                                      */
00017 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00018 /*Genesis3D Version 1.1 released November 15, 1999                            */
00019 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
00020 /*                                                                                      */
00021 /****************************************************************************************/
00022 #include <Windows.h>
00023 #include <Assert.h>
00024 
00025 #include "D3DDrv.h"
00026 #include "GSpan.h"
00027 
00028 SPAN            SpanLines[MAX_SPAN_LINES];
00029 
00030 SPAN_MINMAX     SMinMax[MAX_SPAN_LINES];                        // Linked list of spans for each scanline...
00031 SLIST           ScanHash[MAX_SPANS];                            // hash table for SList
00032 
00033 BOOL            PolyVisible = FALSE;
00034 
00035 int32                   NumWorldPixels = 0;
00036 int32                   NumSpans = 0;
00037 int32                   NumSpanPixels[MAX_SPAN_LINES];
00038 int32                   PolysRendered = 0;
00039 
00040 int32                   CurrentSList = 0;
00041 
00042 const int32 CEIL_FRACT = ( ( 1 << 16)-1);
00043 void DRIVERCC EdgeOutNoUV (int32 x1, int32 y1, int32 x2, int32 y2)
00044 {
00045         int32           Ctmp;
00046         int32           y;
00047         int32           x,m;
00048 
00049         int32           ydelta;
00050         int32           Dir;
00051         int32           Cx1, Cx2, Cy1, Cy2;
00052         SPAN    *pSpans;
00053 
00054         Cx1 = x1;
00055         Cx2 = x2;
00056         Cy1 = y1;
00057         Cy2 = y2;
00058 
00059         if (Cy2 != Cy1)                                                         // This isn't a horizontal line 
00060         {                                                               
00061                 Dir =0;                                                                 // Left side
00062 
00063                 if (Cy2 < Cy1)                                                  // Make sure y2 is greater than y1
00064                 {
00065                         Dir =1;                                                         // Right side
00066 
00067                         Ctmp = Cx1;
00068                         Cx1 = Cx2;
00069                         Cx2 = Ctmp;
00070 
00071                         Ctmp = Cy1;
00072                         Cy1 = Cy2;
00073                         Cy2 = Ctmp;
00074 
00075                 }
00076 
00077                 ydelta = (Cy2 - Cy1);
00078 
00079                 x = (Cx1 << 16) + CEIL_FRACT;            // Allign on int amounts
00080                 m = (((Cx2 - Cx1))<<16) / ydelta;        // How much to increase x each iteration
00081 
00082                 pSpans = &SpanLines[Cy1];
00083 
00084                 if (!Dir)
00085                 {
00086                         for (y = Cy1; y <= Cy2; y++, pSpans++)       
00087                         {
00088                                 pSpans->x1 = (x>>16);
00089                                 x += m;                                                         // Add our constant to x
00090                         }
00091                 }
00092                 else
00093                 {
00094                         for (y = Cy1; y <= Cy2; y++, pSpans++)       
00095                         {
00096                                 pSpans->x2 = (x>>16);
00097                                 x += m;                                                         // Add our constant to x
00098                         }
00099                 }   
00100         } 
00101 }
00102 
00103 void DRIVERCC AddSpanNoUV(int32 x1, int32 x2, int32 y)
00104 {
00105     int32               i, xx2;
00106     SLIST               *LineStart;
00107     SLIST               *Current;
00108         SPAN_MINMAX *pSList;
00109 
00110     assert(y >=0 && y < MAX_SPAN_LINES);
00111         
00112         if (NumSpanPixels[y] >= ClientWindow.Width) 
00113                 return;
00114 
00115     if (x1 > x2)                                                                        // Swap all the coordinates so x1 < x2 
00116     {
00117                 i = x1; 
00118                 x1 = x2; 
00119                 x2 = i;
00120     }
00121 
00122     //if ( (x2 - x1) < 0) 
00123         //      return;                                                                         // Invalid line
00124     
00125     Current = SMinMax[y].First;
00126         
00127         LineStart = NULL;
00128 
00129         pSList = &SMinMax[y];
00130 
00131         // Check to see if there are spans
00132         // in the list yet...
00133         if (!pSList->First) 
00134         {       
00135                 pSList->First = NewSList();     
00136         pSList->First->Last = NULL;
00137         pSList->First->Next = NULL;
00138         pSList->First->Min = x1;
00139         pSList->First->Max = x2;
00140     }
00141     else while (Current != NULL)
00142     {
00143                 if (x1 >= Current->Min && x2 <= Current->Max)
00144                         return;                                                         // This line totally hidden...
00145 
00146                 //if falls before the entire min, max
00147                 if (LineStart == NULL) 
00148                 {
00149                         if (Current == pSList->First)
00150             if (x2 < Current->Min) 
00151                         {
00152                                 SLIST *NewMinMax = NewSList();
00153                 NewMinMax->Next = Current;
00154                 NewMinMax->Last = NULL;
00155                 Current->Last = NewMinMax;
00156                 pSList->First = NewMinMax;
00157                 NewMinMax->Min = x1;
00158                 NewMinMax->Max = x2;
00159                 goto WasNull;
00160             }
00161             // if falls in the middle (but not touching)
00162             if (Current->Next != NULL)
00163             if (x1 > Current->Max && x2 < (Current->Next)->Min) 
00164                         {
00165                 SLIST *NewMinMax = NewSList();
00166                 NewMinMax->Next = Current->Next;
00167                 NewMinMax->Last = Current;
00168                 Current->Next->Last = NewMinMax;
00169                 Current->Next = NewMinMax;
00170                 NewMinMax->Min = x1;
00171                 NewMinMax->Max = x2;
00172                 goto WasNull;
00173             }
00174             // if it falls to the right of all spans
00175             if (Current->Next == NULL)
00176             if (x1 > Current->Max) 
00177                         {
00178                 SLIST *NewMinMax = NewSList();
00179                 Current->Next = NewMinMax;
00180                 NewMinMax->Next = NULL;
00181                 NewMinMax->Last = Current;
00182                 NewMinMax->Min = x1;
00183                 NewMinMax->Max = x2;
00184                 goto WasNull;
00185             }
00186         }
00187                 //if we have already started crossing spans, and we find out
00188                 // that we are in front of a span, then we can bail out...
00189         if (LineStart != NULL)
00190                         if (x2 < Current->Min)
00191                                 goto WasNull;
00192 
00193 
00194         // We now know that we have not fallen into any empty holes.
00195         // We must now check to see what spans, we've crossed...
00196 
00197         // if split by a min/max
00198         if (x1 < Current->Min && x2 > Current->Max) 
00199                 {
00200                         xx2 = Current->Min-1;
00201             Current->Min = x1; 
00202                         
00203                         NumWorldPixels += xx2 - x1 + 1; 
00204                         NumSpanPixels[y] += xx2 - x1 + 1;
00205                         
00206                         if (!PolyVisible) 
00207                         { 
00208                                 PolysRendered++;
00209                                 PolyVisible = 1;
00210                         }
00211             
00212             x1 = Current->Max+1;
00213             Current->Max = x2;
00214             if (LineStart!=NULL) 
00215                                 LineStart->Max = x2;
00216             else
00217                                 LineStart = Current;
00218             goto next;
00219                 }
00220 
00221                 if (x1 <= Current->Max && x2 > Current->Max) 
00222                 {
00223             x1 = Current->Max+1;
00224             Current->Max = x2;
00225             LineStart = Current;
00226             goto next;
00227                 }
00228                 if (x1 < Current->Min && x2 >= Current->Min) 
00229                 {
00230             x2 = Current->Min-1;
00231             Current->Min = x1;
00232             if (LineStart!=NULL) 
00233                                 LineStart->Max = Current->Max;
00234             goto WasNull;
00235         }
00236                 next:;
00237                 Current = Current->Next;
00238     }
00239         WasNull:;
00240 
00241         if (!PolyVisible) 
00242         { 
00243                 PolysRendered++;
00244                 PolyVisible = 1;
00245         }
00246 
00247         NumWorldPixels += x2 - x1 + 1;
00248         NumSpanPixels[y] += x2 - x1 + 1;
00249 }       
00250 
00251 void ResetSList(void)
00252 {
00253         CurrentSList = 0;
00254         NumSpans = 0;
00255 }
00256 
00257 SLIST *NewSList(void)
00258 {
00259 
00260         CurrentSList++;
00261         NumSpans++;
00262 
00263         assert(CurrentSList < MAX_SPANS);
00264 
00265         return &ScanHash[CurrentSList-1];
00266 
00267         return NULL;
00268 }
00269 
00270 void ResetSpans(int32 Rows)
00271 { 
00272         int32           i;
00273 
00274         for (i=0; i<Rows; i++) 
00275         {
00276                 SMinMax[i].First = NULL;
00277                 NumSpanPixels[i] = 0;
00278         }
00279         ResetSList();
00280         NumWorldPixels = 0;
00281 }

Generated on Tue Sep 30 12:35:54 2003 for GTestAndEngine by doxygen 1.3.2