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

TRaster.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  TRaster.C                                                                           */
00003 /*                                                                                      */
00004 /*  Author: Mike Sandige                                                                    */
00005 /*  Description:  API layer for Triangle Rasterizer                                     */
00006 /*                                                                                      */
00007 /*  Code fragments from Chris Hecker's texture mapping articles used with               */
00008 /*  permission.  http://www.d6.com/users/checker                                        */
00009 /*                                                                                      */
00010 /*  The contents of this file are subject to the Genesis3D Public License               */
00011 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00012 /*  compliance with the License. You may obtain a copy of the License at                */
00013 /*  http://www.genesis3d.com                                                            */
00014 /*                                                                                      */
00015 /*  Software distributed under the License is distributed on an "AS IS"                 */
00016 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00017 /*  the License for the specific language governing rights and limitations              */
00018 /*  under the License.                                                                  */
00019 /*                                                                                      */
00020 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00021 /*Genesis3D Version 1.1 released November 15, 1999                            */
00022 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
00023 /*                                                                                      */
00024 /****************************************************************************************/
00025 #include <assert.h>
00026 
00027 #include "TRaster.h"
00028 #include "Triangle.h"
00029 #include "span.h"
00030 #include "spanbuffer.h"
00031 
00032 Span_DrawFunction TRaster_DrawSpan;             // used to draw for current triangle
00033 void GENESISCC TRaster_LightMapSetup(void);
00034 
00035 // Construct different edge-walkers depending on the various rops:
00036 
00037 //SPANEDGES OPTIONS:  TMAP  LSHADE  ZBUF  SBUF
00038 
00039 #define SPANEDGES LSHADE
00040 static void GENESISCC TRaster_SpanEdges_LSHADE(int Height)
00041         {
00042                 #include "SpanEdges_Factory.h"
00043         }
00044 
00045 #define SPANEDGES LSHADE + ZBUF
00046 static void GENESISCC TRaster_SpanEdges_LSHADE_ZBUF(int Height)
00047         {
00048                 #include "SpanEdges_Factory.h"
00049         }
00050 
00051 #define SPANEDGES TMAP + LSHADE 
00052 static void GENESISCC TRaster_SpanEdges_TMAP_LSHADE(int Height)
00053         {
00054                 #include "SpanEdges_Factory.h"
00055         }
00056 
00057 #define SPANEDGES TMAP + LSHADE + ZBUF
00058 static void GENESISCC TRaster_SpanEdges_TMAP_LSHADE_ZBUF(int Height)
00059         {
00060                 #include "SpanEdges_Factory.h"
00061         }
00062 
00063 #define SPANEDGES TMAP + LMAP + ZBUF + SBUF
00064 static void GENESISCC TRaster_SpanEdges_TMAP_LMAP_ZBUF_SBUF(int Height)
00065         {
00066                 #include "SpanEdges_Factory.h"
00067         }
00068 
00069 #define SPANEDGES TMAP + LSHADE + ZBUF + SBUF
00070 static void GENESISCC TRaster_SpanEdges_TMAP_LSHADE_ZBUF_SBUF(int Height)
00071         {
00072                 #include "SpanEdges_Factory.h"
00073         }
00074 
00075 #define SPANEDGES TMAP + LMAP
00076 static void GENESISCC TRaster_SpanEdges_TMAP_LMAP(int Height)
00077         {
00078                 #include "SpanEdges_Factory.h"
00079         }
00080 
00081 #define SPANEDGES TMAP + LMAP + ZBUF
00082 static void GENESISCC TRaster_SpanEdges_TMAP_LMAP_ZBUF(int Height)
00083         {
00084                 #include "SpanEdges_Factory.h"
00085         }
00086 
00087 
00088 typedef void  ( GENESISCC *TRaster_SpanEdgesFunction)(int Height);
00089 
00090 typedef struct
00091 {
00092         geROP ROP;
00093         int Flags;
00094         TRaster_SpanEdgesFunction SpanEdges;
00095 } TRaster_RopInfo;
00096 
00097 
00098 TRaster_RopInfo TRaster_RopTable[GE_ROP_END] =
00099 //                                                              
00100 {//ROP ID                                               
00101 {GE_ROP_LSHADE,                                         LSHADE,                                                                                 TRaster_SpanEdges_LSHADE },             
00102 {GE_ROP_LSHADE_ZSET,                            LSHADE | ZBUF | ZSET,                                                   TRaster_SpanEdges_LSHADE_ZBUF },        
00103 {GE_ROP_LSHADE_ZTEST,                           LSHADE | ZBUF | ZTEST,                                                  TRaster_SpanEdges_LSHADE_ZBUF },        
00104 {GE_ROP_LSHADE_ZTESTSET,                        LSHADE | ZBUF | ZTEST | ZSET,                                   TRaster_SpanEdges_LSHADE_ZBUF },        
00105 {GE_ROP_LSHADE_AFLAT,                           LSHADE | AFLAT,                                                                 TRaster_SpanEdges_LSHADE_ZBUF },        
00106 {GE_ROP_LSHADE_AFLAT_ZSET,                      LSHADE | AFLAT | ZBUF | ZSET,                                   TRaster_SpanEdges_LSHADE_ZBUF },        
00107 {GE_ROP_LSHADE_AFLAT_ZTEST,                     LSHADE | AFLAT | ZBUF | ZTEST,                                  TRaster_SpanEdges_LSHADE_ZBUF },        
00108 {GE_ROP_LSHADE_AFLAT_ZTESTSET,          LSHADE | AFLAT | ZBUF | ZTEST | ZSET,                   TRaster_SpanEdges_LSHADE_ZBUF },        
00109 {GE_ROP_TMAP_LSHADE,                            TMAP | LSHADE,                                                                  TRaster_SpanEdges_TMAP_LSHADE },        
00110 {GE_ROP_TMAP_LSHADE_ZSET,                       TMAP | LSHADE | ZBUF | ZSET,                                    TRaster_SpanEdges_TMAP_LSHADE_ZBUF},
00111 {GE_ROP_TMAP_LSHADE_ZTEST,              TMAP | LSHADE | ZBUF | ZTEST,                                   TRaster_SpanEdges_TMAP_LSHADE_ZBUF},
00112 {GE_ROP_TMAP_LSHADE_ZTESTSET,           TMAP | LSHADE | ZBUF | ZTEST | ZSET,                    TRaster_SpanEdges_TMAP_LSHADE_ZBUF},
00113 {GE_ROP_TMAP_LMAP_ZSET_SBUF,            TMAP | LMAP | ZBUF | ZSET | SBUF,                               TRaster_SpanEdges_TMAP_LMAP_ZBUF_SBUF },
00114 {GE_ROP_TMAP_LSHADE_ZSET_SBUF,          TMAP | LSHADE | ZBUF | ZSET | SBUF,                             TRaster_SpanEdges_TMAP_LSHADE_ZBUF_SBUF },
00115 {GE_ROP_TMAP_LMAP_ZTESTSET,                     TMAP | LMAP | ZBUF | ZTEST | ZSET,                              TRaster_SpanEdges_TMAP_LMAP_ZBUF },
00116 {GE_ROP_TMAP_LSHADE_AFLAT,                      TMAP | LSHADE | AFLAT ,                                                 TRaster_SpanEdges_TMAP_LSHADE },                
00117 {GE_ROP_TMAP_LSHADE_AFLAT_ZSET,         TMAP | LSHADE | AFLAT | ZBUF | ZSET,                    TRaster_SpanEdges_TMAP_LSHADE_ZBUF },   
00118 {GE_ROP_TMAP_LSHADE_AFLAT_ZTEST,        TMAP | LSHADE | AFLAT | ZBUF | ZTEST,                   TRaster_SpanEdges_TMAP_LSHADE_ZBUF },   
00119 {GE_ROP_TMAP_LSHADE_AFLAT_ZTESTSET,     TMAP | LSHADE | AFLAT | ZBUF | ZTEST | ZSET,    TRaster_SpanEdges_TMAP_LSHADE_ZBUF },   
00120 {GE_ROP_TMAP_LSHADE_AMAP,                       TMAP | LSHADE | AMAP,                                                   TRaster_SpanEdges_TMAP_LSHADE },        
00121 {GE_ROP_TMAP_LSHADE_AMAP_ZSET,          TMAP | LSHADE | AMAP | ZBUF | ZSET,                             TRaster_SpanEdges_TMAP_LSHADE_ZBUF },   
00122 {GE_ROP_TMAP_LSHADE_AMAP_ZTEST,         TMAP | LSHADE | AMAP | ZBUF | ZTEST,                    TRaster_SpanEdges_TMAP_LSHADE_ZBUF },   
00123 {GE_ROP_TMAP_LSHADE_AMAP_ZTESTSET,      TMAP | LSHADE | AMAP | ZBUF | ZTEST | ZSET,             TRaster_SpanEdges_TMAP_LSHADE_ZBUF },   
00124 {GE_ROP_TMAP_LMAP_AMAP,                         TMAP | LMAP | AMAP,                                                             TRaster_SpanEdges_TMAP_LMAP },          
00125 {GE_ROP_TMAP_LMAP_AMAP_ZSET,            TMAP | LMAP | AMAP | ZBUF | ZSET,                               TRaster_SpanEdges_TMAP_LMAP_ZBUF },     
00126 {GE_ROP_TMAP_LMAP_AMAP_ZTEST,           TMAP | LMAP | AMAP | ZBUF | ZTEST,                              TRaster_SpanEdges_TMAP_LMAP_ZBUF },     
00127 {GE_ROP_TMAP_LMAP_AMAP_ZTESTSET,        TMAP | LMAP | AMAP | ZBUF | ZTEST | ZSET,               TRaster_SpanEdges_TMAP_LMAP_ZBUF },
00128 {GE_ROP_TMAP_LMAP_AFLAT_ZTESTSET,       TMAP | LMAP | AFLAT | ZBUF |  ZTEST | ZSET,             TRaster_SpanEdges_TMAP_LMAP_ZBUF },
00129 {GE_ROP_TMAP_LSHADE_AMAP_AFLAT,                 TMAP | LSHADE | AMAP | AFLAT,                                                   TRaster_SpanEdges_TMAP_LSHADE },
00130 {GE_ROP_TMAP_LSHADE_AMAP_AFLAT_ZSET,    TMAP | LSHADE | AMAP | AFLAT | ZBUF |  ZSET,                    TRaster_SpanEdges_TMAP_LSHADE_ZBUF },
00131 {GE_ROP_TMAP_LSHADE_AMAP_AFLAT_ZTEST,   TMAP | LSHADE | AMAP | AFLAT | ZBUF |  ZTEST,                   TRaster_SpanEdges_TMAP_LSHADE_ZBUF },
00132 {GE_ROP_TMAP_LSHADE_AMAP_AFLAT_ZTESTSET,TMAP | LSHADE | AMAP | AFLAT | ZBUF |  ZTEST | ZSET,    TRaster_SpanEdges_TMAP_LSHADE_ZBUF },
00133 
00134 };
00135 
00136 
00137 
00138 
00139 void GENESISCC TRaster_LightMapSetup(void)
00140 {
00141         TRaster_Lightmap LM;
00142         Triangle.IsLightMapSetup=GE_TRUE;
00143         LM.MipIndex = Triangle.MipIndex;
00144 
00145         Triangle.LightMapSetup(&LM);
00146 
00147         Triangle.LightMapBits = (LIGHTMAPPIXEL *)LM.BitPtr; 
00148         Triangle.LightMapWidth  = LM.Width;
00149         Triangle.LightMapHeight = LM.Height;
00150 
00151         Triangle.LightMapShiftU = (int)(65536.0f * LM.LightMapShiftU);
00152         Triangle.LightMapScaleU = (int)(256.0f   * LM.LightMapScaleU);
00153 
00154         Triangle.LightMapShiftV = (int)(65536.0f * LM.LightMapShiftV);
00155         Triangle.LightMapScaleV = (int)(256.0f   * LM.LightMapScaleV);
00156 
00157         Triangle.LightMapStride = Triangle.LightMapWidth * 3;
00158         Triangle.LightMapMaxU   = (Triangle.LightMapWidth-1)<<16;
00159         Triangle.LightMapMaxV   = (Triangle.LightMapHeight-1)<<16;
00160 }
00161 
00162 
00163 void GENESISCC TRaster_Setup(int MaxAffineSize,geRDriver_THandle *Dest, geRDriver_THandle *ZBuffer, void (*LightMapSetup)(TRaster_Lightmap *LM))
00164 {
00165         int i;
00166         
00167         assert( MaxAffineSize > 0);
00168         assert( MaxAffineSize < TRASTER_SMALL_DIVIDE_TABLESIZE);
00169         assert( Dest != NULL );
00170         assert( LightMapSetup != NULL );
00171         
00172         Triangle.MaxAffineSize = (geFloat)MaxAffineSize;
00173 
00174 
00175         for (i=1; i<TRASTER_SMALL_DIVIDE_TABLESIZE; i++)
00176                 {
00177                         Triangle.SmallDivideTable[i] = 0x10000/i;
00178                 }
00179         #ifdef  NOISE_FILTER
00180                 for (i=0; i<256; i++)
00181                         {
00182                                 Triangle.RandomTable[i] = (rand() & 0x03)<<24;
00183                         }
00184         #endif
00185 
00186         Triangle.ZMap    = ZBuffer;
00187         Triangle.DestMap = Dest;
00188         Triangle.LightMapSetup = LightMapSetup;
00189 }
00190 
00191 
00192                 
00193                 // expected ranges for pVertices elements:
00194                 //   x,y  (pretty much anything)  but these are in screen space...
00195                 //   z  (0..65536)  
00196                 //   r,g,b:  0..255
00197                 //   a: 0..255
00198                 //   pVertices expected in clockwise winding order.  Counter clockwise will not be rasterized.
00199                 // future: for larger polys, add parameter that allows previous gradient to be reused. (if it was computed)
00200 void GENESISCC TRaster_Rasterize( 
00201                 geROP ROP,
00202                 geRDriver_THandle *Texture,
00203                 int MipIndex,
00204                 const DRV_TLVertex      *pVertices)
00205 {
00206         uint32 DestPtr;
00207         int32  DestWidth;
00208         int Top,Middle,Bottom;
00209         geFloat Y0 = pVertices[0].y; 
00210         geFloat Y1 = pVertices[1].y;
00211         geFloat Y2 = pVertices[2].y;
00212 
00213 
00214         
00215         Triangle_Edge TopToBottom, TopToSplit, SplitToBottom;
00216         int SplitRight;         // set if triangle has two right-side edges (and one left-side edge)
00217 
00218         #ifdef NOISE_FILTER
00219         Triangle.RandomIndex=0;
00220         #endif
00221 
00222         assert( ROP >=0 ) ;
00223         assert( ROP <= GE_ROP_END );
00224 
00225         Triangle.ROPFlags = TRaster_RopTable[ROP].Flags;
00226 
00227         assert( TRaster_RopTable[ROP].SpanEdges != NULL );
00228         assert( ((Triangle.ROPFlags & AFLAT)  && (pVertices[0].a>=0.0f && pVertices[0].a<=255.1f)) || !(Triangle.ROPFlags & AFLAT));
00229         assert( ((Triangle.ROPFlags & LSHADE) && (pVertices[0].r>=0.0f && pVertices[0].r<=255.1f)) || !(Triangle.ROPFlags & LSHADE));
00230         assert( ((Triangle.ROPFlags & LSHADE) && (pVertices[1].r>=0.0f && pVertices[1].r<=255.1f)) || !(Triangle.ROPFlags & LSHADE));
00231         assert( ((Triangle.ROPFlags & LSHADE) && (pVertices[2].r>=0.0f && pVertices[2].r<=255.1f)) || !(Triangle.ROPFlags & LSHADE));
00232         assert( ((Triangle.ROPFlags & LSHADE) && (pVertices[0].g>=0.0f && pVertices[0].g<=255.1f)) || !(Triangle.ROPFlags & LSHADE));
00233         assert( ((Triangle.ROPFlags & LSHADE) && (pVertices[1].g>=0.0f && pVertices[1].g<=255.1f)) || !(Triangle.ROPFlags & LSHADE));
00234         assert( ((Triangle.ROPFlags & LSHADE) && (pVertices[2].g>=0.0f && pVertices[2].g<=255.1f)) || !(Triangle.ROPFlags & LSHADE));
00235         assert( ((Triangle.ROPFlags & LSHADE) && (pVertices[0].b>=0.0f && pVertices[0].b<=255.1f)) || !(Triangle.ROPFlags & LSHADE));
00236         assert( ((Triangle.ROPFlags & LSHADE) && (pVertices[1].b>=0.0f && pVertices[1].b<=255.1f)) || !(Triangle.ROPFlags & LSHADE));
00237         assert( ((Triangle.ROPFlags & LSHADE) && (pVertices[2].b>=0.0f && pVertices[2].b<=255.1f)) || !(Triangle.ROPFlags & LSHADE));
00238         
00239         if (Triangle.ROPFlags & TMAP)
00240                 {
00241                         int W,H;
00242                         assert( Texture != NULL );
00243                         W = Texture->Width >> MipIndex;
00244                         H = Texture->Height >> MipIndex;
00245                         if (Triangle_GradientsCompute(&(Triangle.Gradients),
00246                                                 pVertices,(geFloat)(W),(geFloat)(H))==GE_FALSE)
00247                                 return;  // poly has no area.
00248 
00249                         for(Triangle.StrideShift=1;((1<<Triangle.StrideShift) < W); Triangle.StrideShift++);
00250                         assert( (1<<Triangle.StrideShift) == W );
00251                         if (Triangle.ROPFlags & LMAP)
00252                                 {
00253                                         Triangle.IsLightMapSetup = GE_FALSE;
00254                                 }
00255                         
00256                         Triangle.UMask = W-1;
00257                         Triangle.VMask = H-1;
00258                         assert( MipIndex >= 0 );
00259                         assert( MipIndex <  Texture->MipLevels );
00260                         Triangle.MipIndex = MipIndex;
00261                         Triangle.TextureBits  = (TEXTUREPIXEL *)Texture->BitPtr[MipIndex]; 
00262                         if (Texture->PalHandle)
00263                                 Triangle.Palette  = (Triangle_PaletteEntry *)Texture->PalHandle->BitPtr[0];
00264                 }
00265         else
00266                 {
00267                         if (Triangle_GradientsCompute(&(Triangle.Gradients),pVertices,1.0f,1.0f)==GE_FALSE)
00268                                 return;  // poly has no area.
00269                 }
00270         if (Triangle.ROPFlags & ZBUF)
00271                 {
00272                         assert(Triangle.ZMap != NULL );
00273                         assert(Triangle.ZMap->Width == Triangle.DestMap->Width);
00274 
00275                         Triangle.ZBufferAddressDelta = ((int)(Triangle.ZMap->BitPtr[0])) - ((int)(Triangle.DestMap->BitPtr[0]));
00276                 }
00277         TRaster_DrawSpan = Span_GetDrawFunction(ROP);
00278         A = (int32)(pVertices[0].a / (255.0f/16.0f) );
00279         OneMinusA = 16 - A;
00280                 
00281         // sort vertices in y
00282         if(Y0 < Y1) 
00283                 {
00284                         if(Y2 < Y0) 
00285                                 {                       Top = 2; Middle = 0; Bottom = 1; SplitRight = 1; } 
00286                         else 
00287                                 {
00288                                         if(Y1 < Y2) 
00289                                                 {       Top = 0; Middle = 1; Bottom = 2; SplitRight = 1; } 
00290                                         else 
00291                                                 {       Top = 0; Middle = 2; Bottom = 1; SplitRight = 0; }
00292                                 }
00293                 } 
00294         else 
00295                 {
00296                         if(Y2 < Y1) 
00297                                 {                       Top = 2; Middle = 1; Bottom = 0; SplitRight = 0; } 
00298                         else 
00299                                 {
00300                                         if(Y0 < Y2) 
00301                                                 {       Top = 1; Middle = 0; Bottom = 2; SplitRight = 0; } 
00302                                         else 
00303                                                 {       Top = 1; Middle = 2; Bottom = 0; SplitRight = 1; }
00304                                 }
00305                 }
00306 
00307         
00308         Triangle_EdgeCompute(&TopToBottom,   &(Triangle.Gradients),pVertices,Top,   Bottom, SplitRight);
00309         Triangle_EdgeCompute(&TopToSplit,    &(Triangle.Gradients),pVertices,Top,   Middle, !SplitRight);
00310         Triangle_EdgeCompute(&SplitToBottom,&(Triangle.Gradients),pVertices,Middle,Bottom, !SplitRight);
00311 
00312         // to maximize mmx optimization, there is no floating point from this point on
00313         if(SplitRight) 
00314                 {
00315                         Triangle.Left  = TopToBottom;
00316                         Triangle.Right = TopToSplit;
00317                 } 
00318         else 
00319                 {
00320                         Triangle.Left  = TopToSplit;
00321                         Triangle.Right = TopToBottom;
00322                 }
00323 
00324         DestPtr   = ( uint32 )(Triangle.DestMap->BitPtr[0]);
00325         DestWidth = TOPDOWN_OR_BOTTOMUP(Triangle.DestMap->Width);
00326         Triangle.Left.Dest                = DestPtr + ((Triangle.Left.X  + Triangle.Left.Y * DestWidth)<<DESTPIXEL_SHIFTER);
00327         Triangle.Left.DestStep    = (Triangle.Left.XStep + DestWidth)<<DESTPIXEL_SHIFTER;
00328 
00329 
00330         TRaster_RopTable[ROP].SpanEdges(TopToSplit.Height);
00331 
00332         if(SplitRight) 
00333                 {
00334                         Triangle.Right = SplitToBottom;
00335                 }
00336         else
00337                 {
00338                         Triangle.Left = SplitToBottom;
00339                         Triangle.Left.Dest                = DestPtr + ((Triangle.Left.X  + Triangle.Left.Y * DestWidth)<<DESTPIXEL_SHIFTER);
00340                         Triangle.Left.DestStep    = (Triangle.Left.XStep + DestWidth)<<DESTPIXEL_SHIFTER;
00341                 }
00342 
00343         TRaster_RopTable[ROP].SpanEdges(SplitToBottom.Height);
00344 }

Generated on Tue Sep 30 12:36:34 2003 for GTestAndEngine by doxygen 1.3.2