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 <Assert.h>
00023 
00024 #include "GSpan.h"
00025 #include "GlideDrv.h"
00026 #include "GMain.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 == 0)
00085                 {
00086                         for (y = Cy1; y <= Cy2; y++)                            // Go through each row 
00087                         {
00088                                 pSpans->x1 = (x>>16);
00089                                 pSpans++;
00090                                 x += m;                                                                 // Add our constant to x
00091                         }
00092                 }
00093                 else
00094                 {
00095                         for (y = Cy1; y <= Cy2; y++)                            // Go through each row 
00096                         {
00097                                 pSpans->x2 = (x>>16);
00098                                 pSpans++;
00099                                 x += m;                                                                 // Add our constant to x
00100                         }
00101                 }   
00102         } 
00103 }
00104 
00105 void DRIVERCC AddSpanNoUV(int32 x1, int32 x2, int32 y)
00106 {
00107     int32               i, xx2;
00108     SLIST               *LineStart = NULL;
00109     SLIST               *Current;
00110 
00111     assert(y >=0 && y < MAX_SPAN_LINES);
00112         
00113         // FIXME: Make set ClientWindow.VWidth
00114         if (NumSpanPixels[y] >= ClientWindow.Width) 
00115                 return;
00116 
00117     if (x1 > x2)                                                                        // Swap all the coordinates so x1 < x2 
00118     {
00119                 i = x1; 
00120                 x1 = x2; 
00121                 x2 = i;
00122     }
00123 
00124     //if ( (x2 - x1) < 0) 
00125         //      return;                                                                         // Invalid line
00126     
00127     Current = SMinMax[y].First;
00128         
00129         // Check to see if there are spans
00130         // in the list yet...
00131         if (SMinMax[y].First == NULL) 
00132         {       
00133                 SMinMax[y].First = NewSList();     
00134         (SMinMax[y].First)->Last = NULL;
00135         (SMinMax[y].First)->Next = NULL;
00136         (SMinMax[y].First)->Min = x1;
00137         (SMinMax[y].First)->Max = x2;
00138     }
00139     else while (Current != NULL)
00140     {
00141                 if (x1 >= Current->Min && x2 <= Current->Max)
00142                         return;                                                         // This line totally hidden...
00143 
00144                 //if falls before the entire min, max
00145                 if (LineStart == NULL) 
00146                 {
00147                         if (Current == SMinMax[y].First)
00148             if (x2 < Current->Min) 
00149                         {
00150                                 SLIST *NewMinMax = NewSList();
00151                 NewMinMax->Next = Current;
00152                 NewMinMax->Last = NULL;
00153                 Current->Last = NewMinMax;
00154                 SMinMax[y].First = NewMinMax;
00155                 NewMinMax->Min = x1;
00156                 NewMinMax->Max = x2;
00157                 goto WasNull;
00158             }
00159             // if falls in the middle (but not touching)
00160             if (Current->Next != NULL)
00161             if (x1 > Current->Max && x2 < (Current->Next)->Min) 
00162                         {
00163                 SLIST *NewMinMax = NewSList();
00164                 NewMinMax->Next = Current->Next;
00165                 NewMinMax->Last = Current;
00166                 (Current->Next)->Last = NewMinMax;
00167                 Current->Next       = NewMinMax;
00168                 NewMinMax->Min = x1;
00169                 NewMinMax->Max = x2;
00170                 goto WasNull;
00171             }
00172             // if it falls to the right of all spans
00173             if (Current->Next == NULL)
00174             if (x1 > Current->Max) 
00175                         {
00176                 SLIST *NewMinMax = NewSList();
00177                 Current->Next = NewMinMax;
00178                 NewMinMax->Next = NULL;
00179                 NewMinMax->Last = Current;
00180                 NewMinMax->Min = x1;
00181                 NewMinMax->Max = x2;
00182                 goto WasNull;
00183             }
00184         }
00185                 //if we have already started crossing spans, and we find out
00186                 // that we are in front of a span, then we can bail out...
00187         if (LineStart != NULL)
00188                         if (x2 < Current->Min)
00189                                 goto WasNull;
00190 
00191 
00192         // We now know that we have not fallen into any empty holes.
00193         // We must now check to see what spans, we've crossed...
00194 
00195         // if split by a min/max
00196         if (x1 < Current->Min && x2 > Current->Max) 
00197                 {
00198                         xx2 = Current->Min-1;
00199             Current->Min = x1; 
00200                         
00201                         NumWorldPixels += xx2 - x1 + 1; 
00202                         NumSpanPixels[y] += xx2 - x1 + 1;
00203                         
00204                         if (!PolyVisible) 
00205                         { 
00206                                 PolysRendered++;
00207                                 PolyVisible = 1;
00208                         }
00209             
00210             x1 = Current->Max+1;
00211             Current->Max = x2;
00212             if (LineStart!=NULL) 
00213                                 LineStart->Max = x2;
00214             else
00215                                 LineStart = Current;
00216             goto next;
00217                 }
00218 
00219                 if (x1 <= Current->Max && x2 > Current->Max) 
00220                 {
00221             x1 = Current->Max+1;
00222             Current->Max = x2;
00223             LineStart = Current;
00224             goto next;
00225                 }
00226                 if (x1 < Current->Min && x2 >= Current->Min) 
00227                 {
00228             x2 = Current->Min-1;
00229             Current->Min = x1;
00230             if (LineStart!=NULL) 
00231                                 LineStart->Max = Current->Max;
00232             goto WasNull;
00233         }
00234                 next:;
00235                 Current = Current->Next;
00236     }
00237         WasNull:;
00238 
00239         if (!PolyVisible) 
00240         { 
00241                 PolysRendered++;
00242                 PolyVisible = 1;
00243         }
00244 
00245         NumWorldPixels += x2 - x1 + 1;
00246         NumSpanPixels[y] += x2 - x1 + 1;
00247 }       
00248 
00249 void ResetSList(void)
00250 {
00251         CurrentSList = 0;
00252         NumSpans = 0;
00253 }
00254 
00255 SLIST *NewSList(void)
00256 {
00257 
00258         CurrentSList++;
00259         NumSpans++;
00260 
00261         assert(CurrentSList < MAX_SPANS);
00262 
00263         return &ScanHash[CurrentSList-1];
00264 
00265         return NULL;
00266 }
00267 
00268 void ResetSpans(int32 Rows)
00269 { 
00270         int32           i;
00271 
00272         for (i=0; i<Rows; i++) 
00273         {
00274                 SMinMax[i].First = NULL;
00275                 NumSpanPixels[i] = 0;
00276         }
00277         ResetSList();
00278 }

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