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

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