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

Tclip.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  TClip                                                                               */
00003 /*                                                                                      */
00004 /*  Author: Mike Sandige & Charles Bloom                                                */
00005 /*  Description: Triangle Clipping to the screen rectangle                              */
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 /*  Copyright (C) 1996-1999 Eclipse Entertainment, L.L.C. All Rights Reserved           */
00019 /*                                                                                      */
00020 /****************************************************************************************/
00021 
00022 //#define DO_TIMER
00023 
00024 /*********
00025 
00026 Cbloom Jan 18
00027 TClip gained 2-3 fps
00028 (not counting the gains already from _SetTexture)
00029 
00030 I reorganized the TClip_Triangle function flow to early-out 
00031 for triangles all-in or all-out.  The old code considered this
00032 case, but was not as lean as possible for these most-common cases.
00033 
00034 To solve these problems, flow was changed to :
00035         1. do all compares and accumulated the 3 out bits for each of the five faces
00036                 (so we have 15 bit-flags)
00037         2. then do clips while more clips remain.
00038         3. as a free benefit, the new structure means that Rasterize is only called once
00039                         in TClip_Triangle, so it was inlined.
00040 
00041 Step two results in very fast exiting when no clipping remains.
00042 
00043 
00044 If/When we get the Intel compiler that can optimize ?: to CMOV, speed will improve
00045 even more!
00046 
00047 -----------------------------------
00048 
00049 Timer profiling shows:
00050 (with D3DDrv, in ActView, viewing dema.act)
00051 times are seconds per frame
00052 
00053 default pose : 58.6 fps
00054 TClip_New            : 0.006749
00055 TClip_Rasterize      : 0.006149
00056 
00057 default pose : 52.9 fps
00058 TClip_Old            : 0.007230 : 1.$ %
00059 TClip_Rasterize      : 0.006183 : 1.$ %
00060 
00061 ***********/
00062 
00063 // TClip.c
00064 //  Fast Triangle Clipping
00065 /*}{***********************/
00066 
00067 #include <assert.h>
00068 #include <string.h>
00069 
00070 #include "TClip.h"
00071 #include "engine.h"
00072 #include "bitmap._h"
00073 
00074 #include "list.h"
00075 #include "ram.h"  
00076 
00077 #include "timer.h"
00078 
00079 TIMER_VARS(TClip_Triangle);
00080 
00081 //#define ONE_OVER_Z_PIPELINE   // this has more accuracy, but the slowness of doing 1/ divides
00082 
00083 typedef enum 
00084 {       
00085         BACK_CLIPPING_PLANE = 0,
00086         LEFT_CLIPPING_PLANE,
00087         RIGHT_CLIPPING_PLANE,
00088         TOP_CLIPPING_PLANE,
00089         BOTTOM_CLIPPING_PLANE,
00090         NUM_CLIPPING_PLANES
00091 } geTClip_ClippingPlane;
00092 
00093 // 3 bits for V_IN/OUT flags
00094 #define V_ALL_IN (0)
00095 #define V0_OUT  (1)
00096 #define V1_OUT  (2)
00097 #define V2_OUT  (4)
00098 
00099         // at a=0, result is l;  at a=1, result is h
00100 #define LINEAR_INTERPOLATE(a,l,h)     ((l)+(((h)-(l))*(a)))
00101  
00102 #define RASTERIZECC 
00103 typedef void (RASTERIZECC *geTClip_Rasterize_FuncPtr) (const GE_LVertex * TriVtx);
00104 
00105 typedef struct geTClip_StaticsType
00106 {
00107         geFloat LeftEdge;
00108         geFloat RightEdge;
00109         geFloat TopEdge;
00110         geFloat BottomEdge;
00111         geFloat BackEdge;
00112 
00113         DRV_Driver * Driver;
00114         geEngine        *Engine;
00115         const geBitmap *Bitmap;
00116         geRDriver_THandle * THandle;
00117 
00118         geTClip_Rasterize_FuncPtr RasterizeFunc;
00119 
00120         uint32 RenderFlags;             // LA
00121 
00122 } geTClip_StaticsType;
00123 
00124 /*}{************ Protos ***********/
00125 
00126 static void RASTERIZECC geTClip_Rasterize_Tex(const GE_LVertex * TriVtx);
00127 static void RASTERIZECC geTClip_Rasterize_Gou(const GE_LVertex * TriVtx);
00128 static void GENESISCC geTClip_Split(GE_LVertex *NewVertex,const GE_LVertex *V1,const GE_LVertex *V2,int ClippingPlane);
00129 static void GENESISCC geTClip_TrianglePlane(const GE_LVertex * zTriVertex,geTClip_ClippingPlane ClippingPlane);
00130 static void GENESISCC geTClip_TrianglePlane_Old(const GE_LVertex * zTriVertex,geTClip_ClippingPlane ClippingPlane);
00131 
00132 /*}{************ The State Statics ***********/
00133 
00134 static Link * geTClip_Link = NULL;
00135 static geTClip_StaticsType geTClip_Statics;
00136 static uint32 ActiveRenderFlags = 0;    // LA
00137 
00138 /*}{************ Functions ***********/
00139 
00140 // LA
00141 void GENESISCC geTClip_SetRenderFlags(uint32 newflags)
00142 {
00143         geTClip_Statics.RenderFlags = newflags;
00144         ActiveRenderFlags = newflags;
00145         return;
00146 }
00147 
00148 geBoolean GENESISCC geTClip_Push(void)
00149 {
00150 geTClip_StaticsType * TCI;
00151 
00152         geTClip_Statics.RenderFlags = ActiveRenderFlags; // LA
00153 
00154         if ( ! geTClip_Link )
00155         {
00156                 List_Start();
00157                 geTClip_Link = Link_Create();
00158                 if ( ! geTClip_Link ) 
00159                         return GE_FALSE;
00160         }
00161 
00162         TCI = geRam_Allocate(sizeof(geTClip_StaticsType));
00163         if ( ! TCI )
00164                 return GE_FALSE;
00165         memcpy(TCI,&geTClip_Statics,sizeof(geTClip_StaticsType));
00166 
00167         Link_Push( geTClip_Link , TCI );
00168 
00169         geTClip_Statics.RenderFlags = 0;        // LA, this is needed to set RF = 0 for default after any _Push
00170         
00171         return GE_TRUE;
00172 }
00173 
00174 geBoolean GENESISCC geTClip_Pop(void)
00175 {
00176 geTClip_StaticsType * TCI;
00177         if ( ! geTClip_Link )
00178                 return GE_FALSE;
00179         TCI = Link_Pop( geTClip_Link );
00180         if ( ! TCI )
00181                 return GE_FALSE;
00182         memcpy(&geTClip_Statics,TCI,sizeof(geTClip_StaticsType));
00183         geRam_Free(TCI);
00184 
00185         if ( ! Link_Peek(geTClip_Link) )
00186         {
00187                 Link_Destroy(geTClip_Link);
00188                 geTClip_Link = NULL;
00189                 List_Stop();
00190         }
00191 
00192         ActiveRenderFlags = geTClip_Statics.RenderFlags; // LA, set ARF from newly pop'd statics
00193         
00194         return GE_TRUE;
00195 }
00196 
00197 geBoolean GENESISCC geTClip_SetTexture(const geBitmap * Bitmap)
00198 {
00199         geTClip_Statics.Bitmap = Bitmap;
00200         if ( Bitmap )
00201         {
00202                 geTClip_Statics.THandle = geBitmap_GetTHandle(Bitmap);
00203                 assert(geTClip_Statics.THandle);
00204                 geTClip_Statics.RasterizeFunc = geTClip_Rasterize_Tex;
00205         }
00206         else
00207         {
00208                 geTClip_Statics.THandle = NULL;
00209                 geTClip_Statics.RasterizeFunc = geTClip_Rasterize_Gou;
00210         }
00211 return GE_TRUE;
00212 }
00213 
00214 void GENESISCC geTClip_SetupEdges(
00215         geEngine *Engine,
00216         geFloat LeftEdge, 
00217         geFloat RightEdge,
00218         geFloat TopEdge ,
00219         geFloat BottomEdge,
00220         geFloat BackEdge)
00221 { 
00222         assert(Engine);
00223         memset(&geTClip_Statics,0,sizeof(geTClip_Statics));
00224         geTClip_Statics.Engine          = Engine;
00225         geTClip_Statics.Driver          = Engine->DriverInfo.RDriver; //Engine_GetRDriver(Engine);
00226         geTClip_Statics.LeftEdge        = LeftEdge;
00227         geTClip_Statics.RightEdge       = RightEdge;
00228         geTClip_Statics.TopEdge         = TopEdge;
00229         geTClip_Statics.BottomEdge      = BottomEdge;
00230         geTClip_Statics.BackEdge        = BackEdge;
00231 }
00232 
00233 void geTClip_Done(void)
00234 {
00235         TIMER_REPORT(TClip_Triangle);
00236 }
00237 
00238 void GENESISCC geTClip_Triangle(const GE_LVertex TriVertex[3])
00239 {
00240 
00241         TIMER_P(TClip_Triangle);
00242 
00243 #if 1
00244         geTClip_TrianglePlane(TriVertex,BACK_CLIPPING_PLANE);
00245         //geTClip_TrianglePlane(TriVertex,LEFT_CLIPPING_PLANE);
00246 #else
00247         geTClip_TrianglePlane_Old(TriVertex,BACK_CLIPPING_PLANE);
00248 #endif
00249 
00250         TIMER_Q(TClip_Triangle);
00251 }
00252 
00253 /*}{************ TClip_Rasterize ***********/
00254 
00255 static void RASTERIZECC geTClip_Rasterize_Tex(const GE_LVertex * TriVtx)
00256 {
00257         geTClip_Statics.Driver->RenderMiscTexturePoly((DRV_TLVertex *)TriVtx,
00258                 3,geTClip_Statics.THandle, ActiveRenderFlags); // LA
00259 }
00260 
00261 static void RASTERIZECC geTClip_Rasterize_Gou(const GE_LVertex * TriVtx)
00262 {
00263         geTClip_Statics.Driver->RenderGouraudPoly((DRV_TLVertex *)TriVtx,3,ActiveRenderFlags); // LA
00264 }
00265 
00266 static void GENESISCC geTClip_Rasterize(const GE_LVertex * TriVtx)
00267 {
00268 
00269 // we require GE_LVertex == DRV_TLVertex == GE_TLVertex
00270 //      this is a silly point because the TClip inputs should really be GE_TLVertex anyway !!!!
00271 
00272         if ( geTClip_Statics.THandle )
00273         {
00274                 geTClip_Statics.Driver->RenderMiscTexturePoly((DRV_TLVertex *)TriVtx,
00275                         3,geTClip_Statics.THandle,ActiveRenderFlags);   // LA
00276         }
00277         else
00278         {
00279                 geTClip_Statics.Driver->RenderGouraudPoly((DRV_TLVertex *)TriVtx,
00280                         3,ActiveRenderFlags); // LA
00281         }
00282 }
00283 
00284 /*}{************ TClip_Split ***********/
00285 
00286 static void GENESISCC geTClip_Split(GE_LVertex *NewVertex,const GE_LVertex *V1,const GE_LVertex *V2,int ClippingPlane)
00287 {
00288         geFloat Ratio=0.0f;
00289         geFloat OneOverZ1,OneOverZ2;
00290         
00291         #ifdef ONE_OVER_Z_PIPELINE
00292                 // in here ->Z is really (one over z)
00293         OneOverZ1 = V1->Z;
00294         OneOverZ2 = V2->Z;
00295         #else
00296         OneOverZ1 = 1.0f/V1->Z;
00297         OneOverZ2 = 1.0f/V2->Z;
00298         #endif
00299 
00300         switch (ClippingPlane)
00301         {
00302                 case (BACK_CLIPPING_PLANE):
00303                         assert((V2->Z - V1->Z)!=0.0f);
00304                         Ratio = ((1.0f/geTClip_Statics.BackEdge) - OneOverZ2)/( OneOverZ1 - OneOverZ2 );
00305 
00306                         NewVertex->X = LINEAR_INTERPOLATE(Ratio,(V2->X),(V1->X));
00307                         NewVertex->Y = LINEAR_INTERPOLATE(Ratio,(V2->Y),(V1->Y));
00308                         #ifdef ONE_OVER_Z_PIPELINE
00309                         NewVertex->Z = 1.0f/ geTClip_Statics.BackEdge;
00310                         #else
00311                         NewVertex->Z = geTClip_Statics.BackEdge;
00312                         #endif
00313                 
00314                         break;
00315                 case (LEFT_CLIPPING_PLANE):
00316                         assert((V2->X - V1->X)!=0.0f);
00317                         Ratio = (geTClip_Statics.LeftEdge - V2->X)/( V1->X - V2->X);
00318 
00319                         NewVertex->X = geTClip_Statics.LeftEdge;
00320                         NewVertex->Y = LINEAR_INTERPOLATE(Ratio,(V2->Y),(V1->Y));
00321                         #ifdef ONE_OVER_Z_PIPELINE
00322                         NewVertex->Z = LINEAR_INTERPOLATE(Ratio,OneOverZ2,OneOverZ1);
00323                         #else
00324                         NewVertex->Z = 1.0f/LINEAR_INTERPOLATE(Ratio,OneOverZ2,OneOverZ1);
00325                         #endif
00326         
00327                         break;
00328                 case (RIGHT_CLIPPING_PLANE):
00329                         assert((V2->X - V1->X)!=0.0f);
00330                         Ratio = (geTClip_Statics.RightEdge - V2->X)/( V1->X - V2->X);
00331 
00332                         NewVertex->X = geTClip_Statics.RightEdge;
00333                         NewVertex->Y = LINEAR_INTERPOLATE(Ratio,(V2->Y),(V1->Y));
00334                         #ifdef ONE_OVER_Z_PIPELINE
00335                         NewVertex->Z = LINEAR_INTERPOLATE(Ratio,OneOverZ2,OneOverZ1);
00336                         #else
00337                         NewVertex->Z = 1.0f/LINEAR_INTERPOLATE(Ratio,OneOverZ2,OneOverZ1);
00338                         #endif
00339 
00340                         break;
00341                 case (TOP_CLIPPING_PLANE):
00342                         assert((V2->Y - V1->Y)!=0.0f);
00343                         Ratio = (geTClip_Statics.TopEdge - V2->Y)/( V1->Y - V2->Y);
00344 
00345                         NewVertex->X = LINEAR_INTERPOLATE(Ratio,(V2->X),(V1->X));
00346                         NewVertex->Y = geTClip_Statics.TopEdge;
00347                         #ifdef ONE_OVER_Z_PIPELINE
00348                         NewVertex->Z = LINEAR_INTERPOLATE(Ratio,OneOverZ2,OneOverZ1);
00349                         #else
00350                         NewVertex->Z = 1.0f/LINEAR_INTERPOLATE(Ratio,OneOverZ2,OneOverZ1);
00351                         #endif
00352                         
00353                         break;
00354                 case (BOTTOM_CLIPPING_PLANE):
00355                         assert((V2->Y - V1->Y)!=0.0f);
00356                         Ratio = (geTClip_Statics.BottomEdge - V2->Y)/( V1->Y - V2->Y);
00357 
00358                         NewVertex->X = LINEAR_INTERPOLATE(Ratio,(V2->X),(V1->X));
00359                         NewVertex->Y = geTClip_Statics.BottomEdge;
00360                         #ifdef ONE_OVER_Z_PIPELINE
00361                         NewVertex->Z = LINEAR_INTERPOLATE(Ratio,OneOverZ2,OneOverZ1);
00362                         #else
00363                         NewVertex->Z = 1.0f/LINEAR_INTERPOLATE(Ratio,OneOverZ2,OneOverZ1);
00364                         #endif
00365 
00366                         break;
00367         }
00368 
00369         
00370         {
00371         geFloat OneOverZ1_Ratio;
00372         geFloat OneOverZ2_Ratio;
00373                 #ifdef ONE_OVER_Z_PIPELINE
00374                 OneOverZ1 *= 1.0f / NewVertex->Z;
00375                 OneOverZ2 *= 1.0f / NewVertex->Z;
00376                 #else
00377                 OneOverZ1 *= NewVertex->Z;
00378                 OneOverZ2 *= NewVertex->Z;
00379                 #endif
00380                 OneOverZ1_Ratio = OneOverZ1 * Ratio;
00381                 OneOverZ2_Ratio = OneOverZ2 * Ratio;
00382 
00383                 //  the following is optimized to get rid of a handfull of multiplies. Read:
00384                 //      NewVertex->r = LINEAR_INTERPOLATE(Ratio,(V2->r * OneOverZ2),(V1->r * OneOverZ1));
00385 
00386                 NewVertex->r =(V2->r * OneOverZ2) + (V1->r * OneOverZ1_Ratio) - (V2->r * OneOverZ2_Ratio);
00387                 NewVertex->g =(V2->g * OneOverZ2) + (V1->g * OneOverZ1_Ratio) - (V2->g * OneOverZ2_Ratio);
00388                 NewVertex->b =(V2->b * OneOverZ2) + (V1->b * OneOverZ1_Ratio) - (V2->b * OneOverZ2_Ratio);
00389                 NewVertex->a =(V2->a * OneOverZ2) + (V1->a * OneOverZ1_Ratio) - (V2->a * OneOverZ2_Ratio);
00390                 NewVertex->u =(V2->u * OneOverZ2) + (V1->u * OneOverZ1_Ratio) - (V2->u * OneOverZ2_Ratio);
00391                 NewVertex->v =(V2->v * OneOverZ2) + (V1->v * OneOverZ1_Ratio) - (V2->v * OneOverZ2_Ratio);
00392         }
00393 
00394 }
00395 
00396 
00397 /*}{************ TClip_TrianglePlane ***********/
00398 
00399 static void GENESISCC geTClip_TrianglePlane(const GE_LVertex * TriVertex,
00400                                                                                         geTClip_ClippingPlane ClippingPlane)
00401 {
00402 uint32 OutBits = 0;
00403 
00404         switch(ClippingPlane)
00405         {
00406         case BACK_CLIPPING_PLANE:
00407 
00408                 OutBits |= (TriVertex[0].Z < geTClip_Statics.BackEdge) ? V0_OUT : 0;
00409                 OutBits |= (TriVertex[1].Z < geTClip_Statics.BackEdge) ? V1_OUT : 0;
00410                 OutBits |= (TriVertex[2].Z < geTClip_Statics.BackEdge) ? V2_OUT : 0;
00411 
00412         case LEFT_CLIPPING_PLANE:
00413 
00414                 OutBits |= (TriVertex[0].X < geTClip_Statics.LeftEdge)  ? (V0_OUT<<3) : 0;
00415                 OutBits |= (TriVertex[1].X < geTClip_Statics.LeftEdge)  ? (V1_OUT<<3) : 0;
00416                 OutBits |= (TriVertex[2].X < geTClip_Statics.LeftEdge)  ? (V2_OUT<<3) : 0;
00417 
00418         case RIGHT_CLIPPING_PLANE:
00419 
00420                 OutBits |= (TriVertex[0].X > geTClip_Statics.RightEdge) ? (V0_OUT<<6) : 0;
00421                 OutBits |= (TriVertex[1].X > geTClip_Statics.RightEdge) ? (V1_OUT<<6) : 0;
00422                 OutBits |= (TriVertex[2].X > geTClip_Statics.RightEdge) ? (V2_OUT<<6) : 0;
00423 
00424         case TOP_CLIPPING_PLANE:
00425 
00426                 OutBits |= (TriVertex[0].Y < geTClip_Statics.TopEdge) ? (V0_OUT<<9) : 0;
00427                 OutBits |= (TriVertex[1].Y < geTClip_Statics.TopEdge) ? (V1_OUT<<9) : 0;
00428                 OutBits |= (TriVertex[2].Y < geTClip_Statics.TopEdge) ? (V2_OUT<<9) : 0;
00429 
00430         case BOTTOM_CLIPPING_PLANE:
00431 
00432                 OutBits |= (TriVertex[0].Y > geTClip_Statics.BottomEdge) ?  (V0_OUT<<12) : 0;
00433                 OutBits |= (TriVertex[1].Y > geTClip_Statics.BottomEdge) ?  (V1_OUT<<12) : 0;
00434                 OutBits |= (TriVertex[2].Y > geTClip_Statics.BottomEdge) ?  (V2_OUT<<12) : 0;
00435 
00436         case NUM_CLIPPING_PLANES:
00437                 break;
00438         }
00439 
00440         if ( OutBits )
00441         {
00442         GE_LVertex NewTriVertex[3];
00443 
00444         memset(NewTriVertex, '\0',sizeof(GE_LVertex)*(3));
00445 
00446                 ClippingPlane = 0;
00447                 for(;;)
00448                 {
00449                         assert(ClippingPlane < NUM_CLIPPING_PLANES);
00450 
00451                         switch ( OutBits & 7 )
00452                         {
00453                                 case (V_ALL_IN):  //NOT CLIPPED
00454                                         OutBits >>= 3;
00455                                         ClippingPlane ++;
00456                                         continue;
00457 
00458                                 // these all return:
00459 
00460                                 case (V0_OUT):
00461                                         NewTriVertex[0] = TriVertex[2];
00462                                         geTClip_Split(&(NewTriVertex[1]),TriVertex+0,TriVertex+2,ClippingPlane);
00463                                         NewTriVertex[2] = TriVertex[1];
00464 
00465                                         geTClip_TrianglePlane(NewTriVertex,ClippingPlane+1);
00466 
00467                                         NewTriVertex[0] = NewTriVertex[1];
00468                                         geTClip_Split(&(NewTriVertex[1]),TriVertex+0,TriVertex+1,ClippingPlane);
00469 
00470                                         //<> could gain a little speed like this, but who cares?
00471                                         //      if ( ! (OutBits>>3) )
00472                                         //              goto Rasterize
00473                                         //      else
00474                                         geTClip_TrianglePlane(NewTriVertex,ClippingPlane+1); 
00475                                         return;
00476 
00477                                 case (V1_OUT):
00478                                         NewTriVertex[0] = TriVertex[0];
00479                                         geTClip_Split(&(NewTriVertex[1]),TriVertex+0,TriVertex+1,ClippingPlane);
00480                                         NewTriVertex[2] = TriVertex[2];
00481 
00482                                         geTClip_TrianglePlane(NewTriVertex,ClippingPlane+1);
00483 
00484                                         NewTriVertex[0] = NewTriVertex[1];
00485                                         geTClip_Split(&(NewTriVertex[1]),TriVertex+1,TriVertex+2,ClippingPlane);
00486                                         
00487                                         geTClip_TrianglePlane(NewTriVertex,ClippingPlane+1); 
00488                                         return;
00489 
00490                                 case (V0_OUT + V1_OUT):
00491                                         NewTriVertex[0] = TriVertex[2];
00492                                         geTClip_Split(&(NewTriVertex[1]),TriVertex+0,TriVertex+2,ClippingPlane);
00493                                         geTClip_Split(&(NewTriVertex[2]),TriVertex+1,TriVertex+2,ClippingPlane);
00494                                 
00495                                         geTClip_TrianglePlane(NewTriVertex,ClippingPlane+1); 
00496                                         return;
00497 
00498                                 case (V2_OUT):
00499                                         NewTriVertex[0] = TriVertex[1];
00500                                         geTClip_Split(&(NewTriVertex[1]),TriVertex+1,TriVertex+2,ClippingPlane);
00501                                         NewTriVertex[2] = TriVertex[0];
00502 
00503                                         geTClip_TrianglePlane(NewTriVertex,ClippingPlane+1);
00504 
00505                                         NewTriVertex[0] = NewTriVertex[1];
00506                                         geTClip_Split(&(NewTriVertex[1]),TriVertex+0,TriVertex+2,ClippingPlane);
00507 
00508                                         geTClip_TrianglePlane(NewTriVertex,ClippingPlane+1);
00509                                         return;
00510 
00511                                 case (V2_OUT + V0_OUT):
00512                                         NewTriVertex[0] = TriVertex[1];
00513                                         geTClip_Split(&(NewTriVertex[1]),TriVertex+1,TriVertex+2,ClippingPlane);
00514                                         geTClip_Split(&(NewTriVertex[2]),TriVertex+0,TriVertex+1,ClippingPlane);
00515 
00516                                         geTClip_TrianglePlane(NewTriVertex,ClippingPlane+1);
00517                                         return;
00518 
00519                                 case (V2_OUT + V1_OUT):
00520                                         NewTriVertex[0] = TriVertex[0];
00521                                         geTClip_Split(&(NewTriVertex[1]),TriVertex+0,TriVertex+1,ClippingPlane);
00522                                         geTClip_Split(&(NewTriVertex[2]),TriVertex+0,TriVertex+2,ClippingPlane);
00523 
00524                                         geTClip_TrianglePlane(NewTriVertex,ClippingPlane+1);
00525                                         return;
00526 
00527                                 case (V2_OUT + V1_OUT + V0_OUT):
00528                                         /* TOTALLY CLIPPED */
00529                                         return;
00530                         }
00531                 }
00532         }
00533 
00534 #if 0 // {
00535 
00536         // this eliminates an 'if' , but doesn't seem to help :^(
00537         // presumably because it's a predictable branch
00538         geTClip_Statics.RasterizeFunc(TriVertex);
00539 
00540 #else //}{
00541 
00542         if ( geTClip_Statics.THandle )
00543         {
00544                 geTClip_Statics.Driver->RenderMiscTexturePoly((DRV_TLVertex *)TriVertex,
00545                         3,geTClip_Statics.THandle,ActiveRenderFlags); // LA
00546         }
00547         else
00548         {
00549                 geTClip_Statics.Driver->RenderGouraudPoly((DRV_TLVertex *)TriVertex,3,ActiveRenderFlags); // LA
00550         }
00551 
00552 #endif //}
00553 
00554 }
00555 
00556 // LA - this is for completely onscreen-only triangles
00557 void GENESISCC geTClip_UnclippedTriangle(const GE_LVertex TriVertex[3])
00558 {
00559         if ( geTClip_Statics.THandle )
00560         {
00561                 geTClip_Statics.Driver->RenderMiscTexturePoly((DRV_TLVertex *)TriVertex,
00562                         3,geTClip_Statics.THandle,ActiveRenderFlags);
00563         }
00564         else
00565         {
00566                 geTClip_Statics.Driver->RenderGouraudPoly((DRV_TLVertex *)TriVertex,3,ActiveRenderFlags);
00567         }
00568         return;
00569 }
00570 
00571 /*}{*********** EOF ************/

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