00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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;
00033 void GENESISCC TRaster_LightMapSetup(void);
00034
00035
00036
00037
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 {
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
00194
00195
00196
00197
00198
00199
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;
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;
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;
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
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
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 }