/****************************************************************************************** FILE : CLIP.C VERS : 1.00 \ Philippe Vimont DATE : 15.05.98 *******************************************************************************************/ #include "Gli_st.h" #include "GLI_Defn.h" #include "polygon.h" #include "mater_st.h" #include "light_st.h" #include "PvObj_st.h" #include "Liste.h" #include "watrplan.h" #include "proj.h" #include "vpt3D.h" #include "camera.h" #include "material.h" #include "texture.h" #include "DLLCom.h" #include "TEX.h" #include "PRF.h" #ifdef SGL2 #include #endif #ifdef __cplusplus extern "C" { #endif #ifdef ZARMA }}} #endif #include "drawflags.h" /* collect the functions we need to call*/ /* we need to set this to zero somewhere*/ unsigned long ulFuncMask; char temp_string[100]; \ /* -----------------------------------------------------------------------------------------*/ /* Global variable for optimisation */ /*---------------------------------------------------------------------------------------------*/ extern GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BIG_GLOBALS; static float fAddU,fAddV,fConstantMirrorZValue; static GEO_tdstTripledIndex *p_stCurrentTriangle , *p_stCurrentTriangleUV , *p_stLastTriangle; static GEO_tdstElementIndexedTriangles *p_stCurrentElementIndexedTriangle ; static long fX_CMP_Optimize , fY_CMP_Optimize; static long fXMin_CLIP_Optimize , fYMin_CLIP_Optimize , fXMax_CLIP_Optimize , fYMax_CLIP_Optimize ; static unsigned long *footptr; static ACP_tdst2DUVValues *d_stVirtualUV[3]; extern void GLI_vDoTextureSelection(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT); extern void GLI_vSetGlobalAlpha(float Alpha); #define GLI_C_lCLIP_ALL (GLI_C_ClipMaskXMin | GLI_C_ClipMaskXMax | GLI_C_ClipMaskYMin | GLI_C_ClipMaskYMax ) /* -----------------------------------------------------------------------------------------*/ /**********************************************************************************************/ /* Name: GLI_vSetZClip*/ /* Goal: */ /* Code: Philippe Vimont */ /* OPTIMMIZED : No*/ /**********************************************************************************************/ void GLI_DRV_vSetZClip(float ZClip,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT) { p_stGlobaleMT -> fZClipping = ZClip; p_stGlobaleMT -> fWClipping = 1.0f / ZClip; } /**********************************************************************************************/ /* Name: GLI_vSetClipWindow*/ /* Goal: */ /* Code: Philippe Vimont */ /* OPTIMMIZED : No*/ /**********************************************************************************************/ void GLI_DRV_vSetClipWindow(float fXMin,float fXMax,float fYMin,float fYMax,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT) { p_stGlobaleMT->fXMinClipping = fXMin; p_stGlobaleMT->fXMaxClipping = fXMax; p_stGlobaleMT->fYMinClipping = fYMin; p_stGlobaleMT->fYMaxClipping = fYMax; } /**********************************************************************************************/ /* Name: GLI_ulInterpol2PackedColor*/ /* Goal: interpol 2 unsigned long coded colors with a float [0.0 .. 1.0f]*/ /* Code: Philippe Vimont */ /* OPTIMMIZED : No*/ /**********************************************************************************************/ unsigned long GLI_ulInterpol2PackedColor(unsigned long ulP1,unsigned long ulP2,float fZClipLocalCoef) { unsigned long RetValue,Interpoler; if (fZClipLocalCoef >= 0.98f) return ulP2; if (fZClipLocalCoef <= 0.02f) return ulP1; *((float *)&Interpoler) = fZClipLocalCoef + 32768.0f + 16384.0f; RetValue = (Interpoler & 128) ? (ulP2 & 0xfefefefe) >> 1 : (ulP1 & 0xfefefefe) >> 1; RetValue += (Interpoler & 64) ? (ulP2 & 0xfcfcfcfc) >> 2 : (ulP1 & 0xfcfcfcfc) >> 2; RetValue += (Interpoler & 32) ? (ulP2 & 0xf8f8f8f8) >> 3 : (ulP1 & 0xf8f8f8f8) >> 3; RetValue += (Interpoler & 16) ? (ulP2 & 0xf0f0f0f0) >> 4 : (ulP1 & 0xf0f0f0f0) >> 4; RetValue += (Interpoler & 8) ? (ulP2 & 0xe0e0e0e0) >> 5 : (ulP1 & 0xe0e0e0e0) >> 5; RetValue += (Interpoler & 4) ? (ulP2 & 0xc0c0c0c0) >> 6 : (ulP1 & 0xc0c0c0c0) >> 6; RetValue += (Interpoler & 2) ? (ulP2 & 0x80808080) >> 7 : (ulP1 & 0x80808080) >> 7; return RetValue; } /*void GLI_vInformWaterNoise(GLI_tdstAligned3DVector *p_Point,GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BG);*/ /* -----------------------------------------------------------------------------------------*/ /* Stack function's stuff */ /*---------------------------------------------------------------------------------------------*/ #define GLI_FuncNodeBegin(a) static void GLI_INTERFACE_FUNC(a) (void) static long lActualFunction; static void GLI_fn_LastFunc(void) {}; static void (* GLI_p_fn_ListOfFunc[20])(void) ; static void (** GLI_fnCurrentFunc)(void) ; static void GLI_M_ClearFuncList() { ulFuncMask = 0; lActualFunction = 0; GLI_p_fn_ListOfFunc[0] = GLI_fn_LastFunc; } /* static void GLI_M_AddFunc(void (* Func)(void)) */ #define GLI_M_AddFunc( Func ) \ (GLI_p_fn_ListOfFunc[lActualFunction++] = Func) /* Print out ulFuncMask to Error log here if benching*/ #define GLI_M_CallFirstFunc() \ {\ GLI_fnCurrentFunc = GLI_p_fn_ListOfFunc; \ (*(GLI_fnCurrentFunc))(); \ } #define GLI_M_CallNextFunc() (*(++GLI_fnCurrentFunc))(); #define GLI_M_CallNextFuncAndSave() \ {\ void (** GLI_fnCurrentFuncSave)(void) ;\ GLI_fnCurrentFuncSave = GLI_fnCurrentFunc;\ (*(++GLI_fnCurrentFunc))();\ GLI_fnCurrentFunc = GLI_fnCurrentFuncSave ;\ } #define GLI_M_TriangleIsOut() return /* -----------------------------------------------------------------------------------------*/ /* ZList function stuff */ /*---------------------------------------------------------------------------------------------*/ void GLI_DRV_xClearViewingList ( void ) { unsigned long ulTableCounter; if (GLI_BIG_GLOBALS -> p_TheZListe == NULL) return; GLI_BIG_GLOBALS -> p_TheZListe -> p_CurrentPoint = GLI_BIG_GLOBALS -> p_TheZListe -> p_TableOfPoints; GLI_BIG_GLOBALS -> p_TheZListe -> p_stCurrentZNode = GLI_BIG_GLOBALS -> p_TheZListe -> aDEF_tdstZListeNodes; for (ulTableCounter = 0; ulTableCounter < GLI_NumberOfZListes ; ulTableCounter ++) { GLI_BIG_GLOBALS -> p_TheZListe -> lMinValue[ulTableCounter] = 1 << GLI_MaxZEntryPO2; GLI_BIG_GLOBALS -> p_TheZListe -> lMaxValue[ulTableCounter] = 0; } } void GLI_v_AddNodeInZList(float Z) { unsigned short index; index = (unsigned short )(((*(unsigned long *)&Z) >> 16) - 13000) & ((1 << GLI_MaxZEntryPO2) - 1); if( GLI_BIG_GLOBALS->p_TheZListe->lMinValue[ GLI_BIG_GLOBALS->ulCurrentZTable ] > index ) GLI_BIG_GLOBALS->p_TheZListe->lMinValue[ GLI_BIG_GLOBALS->ulCurrentZTable ] = index; if( GLI_BIG_GLOBALS->p_TheZListe->lMaxValue[ GLI_BIG_GLOBALS->ulCurrentZTable ] < index ) GLI_BIG_GLOBALS->p_TheZListe->lMaxValue[ GLI_BIG_GLOBALS->ulCurrentZTable ] = index; GLI_BIG_GLOBALS->p_TheZListe->p_stCurrentZNode->p_ThreePoints = GLI_BIG_GLOBALS->p_TheZListe->p_CurrentPoint; GLI_BIG_GLOBALS->p_TheZListe->p_stCurrentZNode->p_TextureOfTheTriangle = GLI_BIG_GLOBALS->p_stCurrentTexture; /**/ GLI_BIG_GLOBALS->p_TheZListe->p_stCurrentZNode->p_stMaterial = GLI_BIG_GLOBALS->hCurrentMaterial; GLI_BIG_GLOBALS->p_TheZListe->p_stCurrentZNode->lCurrentDrawMask = GLI_BIG_GLOBALS->lCurrentDrawMask & ~GLI_C_lIsWriteZBuffer; GLI_BIG_GLOBALS->p_TheZListe->p_stCurrentZNode->p_stFogParams = GLI_BIG_GLOBALS->p_stActiveFog ; GLI_BIG_GLOBALS->p_TheZListe->p_stCurrentZNode->p_NextNode = GLI_BIG_GLOBALS->p_TheZListe->aDEF_p_tdstTableOfZentryNearestOfWaterPlane[ index + ( GLI_BIG_GLOBALS->ulCurrentZTable << GLI_MaxZEntryPO2 ) ]; GLI_BIG_GLOBALS->p_TheZListe->aDEF_p_tdstTableOfZentryNearestOfWaterPlane[ index + ( GLI_BIG_GLOBALS->ulCurrentZTable << GLI_MaxZEntryPO2 ) ] = GLI_BIG_GLOBALS->p_TheZListe->p_stCurrentZNode; GLI_BIG_GLOBALS->p_TheZListe->p_stCurrentZNode++; } #define GLI_M_InitSprite()\ {\ SetX(CurrentDestXYZ[0],a4_st2DVertex [0] . xX);\ SetY(CurrentDestXYZ[0],a4_st2DVertex [0] . xY);\ SetX(CurrentDestXYZ[1],a4_st2DVertex [1] . xX);\ SetY(CurrentDestXYZ[1],a4_st2DVertex [1] . xY);\ SetX(CurrentDestXYZ[2],a4_st2DVertex [2] . xX);\ SetY(CurrentDestXYZ[2],a4_st2DVertex [2] . xY);\ SetX(CurrentDestXYZ[3],a4_st2DVertex [3] . xX);\ SetY(CurrentDestXYZ[3],a4_st2DVertex [3] . xY);\ SetZ(CurrentDestXYZ[0],xZ );\ SetZ(CurrentDestXYZ[1],xZ );\ SetZ(CurrentDestXYZ[2],xZ );\ SetZ(CurrentDestXYZ[3],xZ );\ SetPackedColor( CurrentDestXYZ[0] , p_stGlobaleMT -> ulColorInitForSprite);\ SetPackedColor( CurrentDestXYZ[1] , p_stGlobaleMT -> ulColorInitForSprite);\ SetPackedColor( CurrentDestXYZ[2] , p_stGlobaleMT -> ulColorInitForSprite);\ SetPackedColor( CurrentDestXYZ[3] , p_stGlobaleMT -> ulColorInitForSprite);\ } #define GLI_M_InitLine()\ {\ SetX(CurrentDestXYZ[0],p_st2DVertex1->xX);\ SetY(CurrentDestXYZ[0],p_st2DVertex1->xY);\ SetX(CurrentDestXYZ[1],p_st2DVertex2->xX);\ SetY(CurrentDestXYZ[1],p_st2DVertex2->xY);\ SetZ(CurrentDestXYZ[0],p_stVertex1->xZ );\ SetZ(CurrentDestXYZ[1],p_stVertex2->xZ );\ SetPackedColor(CurrentDestXYZ[0],p_st2DVertex1->ulPackedColor );\ SetPackedColor(CurrentDestXYZ[1],p_st2DVertex2->ulPackedColor );\ } /*---------------------------------------------------------------------------------------------*/ /* Kamui specific*/ /*---------------------------------------------------------------------------------------------*/ #ifdef KAMUI #include "Kamui\Acces_KAMUI.c" #include "Acces_ALL.c" #endif /*---------------------------------------------------------------------------------------------*/ /* SGL2 specific*/ /*---------------------------------------------------------------------------------------------*/ #ifdef SGL2 #include "SGL2\Acces_SGL2.c" #include "Acces_ALL.c" #endif /*---------------------------------------------------------------------------------------------*/ /* VOODOO1 specific*/ /*---------------------------------------------------------------------------------------------*/ #ifdef GLIDE2 #include "GLIDE2\SRC\Acces_GLIDE2.c" #include "Acces_ALL.c" #endif /*---------------------------------------------------------------------------------------------*/ /* VOODOO1 specific with multitexture*/ /*---------------------------------------------------------------------------------------------*/ #ifdef GLIDE2MT #include "GLIDE2MT\SRC\Glide2MT_Acces.c" #include "Acces_ALL.c" #endif /*---------------------------------------------------------------------------------------------*/ /* VOODOO2 specific*/ /*---------------------------------------------------------------------------------------------*/ #ifdef GLIDE3 #include "GLIDE3\SRC\GLIDE3_Acces.c" #include "Acces_ALL.c" #endif /*---------------------------------------------------------------------------------------------*/ /* DirectX6 specific*/ /*---------------------------------------------------------------------------------------------*/ #ifdef GLI_DIRECTX6 #include "DirectX6\Src\DX6_Acces.c" #include "Acces_ALL.c" #endif /*---------------------------------------------------------------------------------------------*/ /* OpenGL specific*/ /*---------------------------------------------------------------------------------------------*/ #ifdef GLI_OPENGL #include "OpenGL\Src\OGL_Acces.c" #include "Acces_ALL.c" #endif /* -----------------------------------------------------------------------------------------*/ /* ZList Draw stuff */ /*---------------------------------------------------------------------------------------------*/ void GLI_vDoTransparentTextureSelection(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT); void GLI_fn_vSetRenderParametersBeforeTransparencyFace( void ); void GLI_DRV_xSendListToViewport ( GLD_tdstViewportAttributes *p_stVpt ) { GLI_tdstOneNodeOfZListe *p_CuurentNode,**p_TableEntry,**p_LastTableEntry; unsigned long ulTableCounter; if (GLI_BIG_GLOBALS->p_TheZListe == NULL) return; GLI_BIG_GLOBALS -> lCurrentDrawMask = 0xFFFFFFFF; GLI_BIG_GLOBALS -> p_stCurrentTexture = NULL; GLI_MDRV_vSetGlobalAlpha(128); GLI_BeforeDraw(); GLI_fn_vSetRenderParametersBeforeTransparencyFace(); for (ulTableCounter = 0; ulTableCounter < GLI_NumberOfZListes; ulTableCounter ++) { if ( GLI_BIG_GLOBALS->p_TheZListe->lMaxValue[ulTableCounter] < GLI_BIG_GLOBALS->p_TheZListe->lMinValue[ulTableCounter] ) continue; p_TableEntry = GLI_BIG_GLOBALS -> p_TheZListe -> aDEF_p_tdstTableOfZentryNearestOfWaterPlane + (ulTableCounter << GLI_MaxZEntryPO2); p_LastTableEntry = p_TableEntry + GLI_BIG_GLOBALS -> p_TheZListe -> lMaxValue[ulTableCounter]; p_TableEntry += GLI_BIG_GLOBALS -> p_TheZListe -> lMinValue[ulTableCounter]; /*p_LastTableEntry = p_TableEntry + GLI_BIG_GLOBALS -> p_TheZListe -> lMaxValue[ulTableCounter];*/ while (p_TableEntry <= p_LastTableEntry) { p_CuurentNode = *(p_TableEntry); while (p_CuurentNode != NULL) { if ( ( GLI_BIG_GLOBALS->p_stCurrentTexture != p_CuurentNode->p_TextureOfTheTriangle) || ( GLI_BIG_GLOBALS->lCurrentDrawMask != (long) p_CuurentNode->lCurrentDrawMask) || ( GLI_BIG_GLOBALS->p_stLastComputedFog != p_CuurentNode->p_stFogParams) ) { GLI_AfterDraw(); GLI_BIG_GLOBALS->lCurrentDrawMask = p_CuurentNode->lCurrentDrawMask ; GLI_BIG_GLOBALS->p_stCurrentTexture = p_CuurentNode->p_TextureOfTheTriangle; /*GLI_BIG_GLOBALS->hCurrentMaterial = NULL;*/ GLI_BIG_GLOBALS->hCurrentMaterial = p_CuurentNode->p_stMaterial; /* * fog */ if (p_CuurentNode->p_stFogParams) { GLI_BIG_GLOBALS->xFogIsOn = 1; GLI_BIG_GLOBALS->p_stActiveFog = p_CuurentNode->p_stFogParams; } else { GLI_BIG_GLOBALS->p_stLastComputedFog = NULL; GLI_BIG_GLOBALS->p_stActiveFog = NULL; GLI_BIG_GLOBALS->xFogIsOn = 0; } /*GLI_AfterDraw();*/ GLI_BeforeDraw(); GLI_vDoTransparentTextureSelection(GLI_BIG_GLOBALS ); } if (p_CuurentNode -> lCurrentDrawMask & GLI_C_lIsGouraud ) GLI_vDrawZSortedTriangle(p_CuurentNode -> p_ThreePoints); else GLI_vDrawZSortedQuad(p_CuurentNode -> p_ThreePoints); p_CuurentNode = p_CuurentNode -> p_NextNode; } *(p_TableEntry++) = NULL; } } GLI_AfterDraw(); GLI_DRV_xClearViewingList(); } /**********************************************************************************************/ /* Name: GLI_DRV_xSendElementTIToClip_TRIANGLES*/ /* Goal: Draw an element indexed triangles..*/ /* Code: Philippe Vimont */ /* OPTIMMIZED : No*/ /**********************************************************************************************/ void GLI_DRV_xSendElementTIToClip_TRIANGLES( GEO_tdstElementIndexedTriangles *p_stLocalElementIndexedTriangle , GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT) { ACP_tdxIndex xTriangleCounter ; #ifdef SGL2 long AMirrorIsDetectedSave; AMirrorIsDetectedSave = GLI_BIG_GLOBALS->lAMirrorIsDetected; GLI_BIG_GLOBALS->lAMirrorIsDetected &= 0xffffffff - 2; #endif p_stCurrentElementIndexedTriangle = p_stLocalElementIndexedTriangle; GLI_ReComputeClippingMask(); p_stGlobaleMT -> lCurrentDrawMask |= GLI_C_lIsGouraud; fConstantMirrorZValue = 10.0f; GLI_M_ClearFuncList(); /* -----------------------------------------------------------------------------------*/ /* First function*/ /* ------------------------------------------------------------------------------------*/ GLI_M_AddFunc(GLI_vComputeXYZ); ulFuncMask |= Flag_GLI_vComputeXYZ; /* -----------------------------------------------------------------------------------*/ /* Set UV*/ /* ------------------------------------------------------------------------------------*/ /*if (p_stGlobaleMT-> p_stCurrentTexture != NULL)*/ { if (!(p_stGlobaleMT->lCurrentDrawMask & GLI_C_lIsNotChromed)) GLI_M_AddFunc(GLI_vSetChromeUVW); else GLI_M_AddFunc(GLI_vSetNormalUVW); } /* -----------------------------------------------------------------------------------*/ /* Fog effect*/ /* ------------------------------------------------------------------------------------*/ if (GLI_BIG_GLOBALS->xFogIsOn) { GLI_M_AddFunc(GLI_vSetSpecular); ulFuncMask |= Flag_GLI_vSetSpecular; } /* ------------------------------------------------------------------------------------*/ /* MIRROR - WATER CLIPPING - OTHER CLIPPING ..... */ /* ------------------------------------------------------------------------------------*/ /* It coould be here*/ /* -----------------------------------------------------------------------------------*/ /* First CullingZ */ /* ------------------------------------------------------------------------------------*/ if (GLI_BIG_GLOBALS -> lClippingModeMask & GLI_C_ClipMaskZ) { GLI_M_AddFunc(GLI_FastZCull); ulFuncMask |= Flag_GLI_FastZCull; } /* -----------------------------------------------------------------------------------*/ /* First Mirror Culling*/ /* ------------------------------------------------------------------------------------*/ if (!(GLI_BIG_GLOBALS -> lCurrentDrawMask & GLI_C_lNotHideWhatIsUnderWater)) { GLI_M_AddFunc(GLI_FastMirrorCulling); ulFuncMask |= Flag_GLI_FastMirrorCulling; } /* -----------------------------------------------------------------------------------*/ /* culing X Y*/ /* ------------------------------------------------------------------------------------*/ if (GLI_BIG_GLOBALS -> lClippingModeMask & GLI_C_lCLIP_ALL) { if ( (GLI_BIG_GLOBALS -> lClippingModeMask & GLI_C_lCLIP_ALL) == GLI_C_lCLIP_ALL ) { GLI_M_AddFunc(GLI_bCullingXYALL); ulFuncMask |= Flag_GLI_bCullingXYALL; } else { switch (GLI_BIG_GLOBALS -> lClippingModeMask & (GLI_C_ClipMaskXMin | GLI_C_ClipMaskXMax )) { case 0:break; case GLI_C_ClipMaskXMin:GLI_M_AddFunc(GLI_bCullingXMin); ulFuncMask |= Flag_GLI_bCullingXMin; break; case GLI_C_ClipMaskXMax:GLI_M_AddFunc(GLI_bCullingXMax); ulFuncMask |= Flag_GLI_bCullingXMax; break; case GLI_C_ClipMaskXMin + GLI_C_ClipMaskXMax:GLI_M_AddFunc(GLI_bCullingXMax_XMin); ulFuncMask |= Flag_GLI_bCullingXMax_XMin; break; } switch (GLI_BIG_GLOBALS -> lClippingModeMask & (GLI_C_ClipMaskYMin | GLI_C_ClipMaskYMax )) { case 0:break; case GLI_C_ClipMaskYMin:GLI_M_AddFunc(GLI_bCullingYMin); ulFuncMask |= Flag_GLI_bCullingYMin; break; case GLI_C_ClipMaskYMax:GLI_M_AddFunc(GLI_bCullingYMax); ulFuncMask |= Flag_GLI_bCullingYMax; break; case GLI_C_ClipMaskYMin + GLI_C_ClipMaskYMax:GLI_M_AddFunc(GLI_bCullingYMax_YMin); ulFuncMask |= Flag_GLI_bCullingYMax_YMin; break; } } } /* ------------------------------------------------------------------------------------*/ /* MIRROR - WATER CLIPPING - OTHER CLIPPING ..... Done after culling*/ /* ------------------------------------------------------------------------------------*/ if (GLI_BIG_GLOBALS -> lClippingModeMask & GLI_C_ClipMaskWater) { if (GLI_BIG_GLOBALS -> lCurrentDrawMask & GLI_C_lNotHideWhatIsUnderWater) { GLI_M_AddFunc(GLI_FastWaterCLipping); ulFuncMask |= Flag_GLI_FastWaterCLipping; } else { GLI_M_AddFunc(GLI_FastMirrorCLipping); ulFuncMask |= Flag_GLI_FastMirrorCLipping; } } /* ------------------------------------------------------------------------------------*/ /* Z CLIPPING;*/ /* ------------------------------------------------------------------------------------*/ if (GLI_BIG_GLOBALS -> lClippingModeMask & GLI_C_ClipMaskZ) { GLI_M_AddFunc(GLI_vZClipping); ulFuncMask |= Flag_GLI_vZClipping; } /* ------------------------------------------------------------------------------------*/ /* BACKFACE INIT;*/ /* ------------------------------------------------------------------------------------*/ if (p_stGlobaleMT -> lCurrentDrawMask & GLI_C_lIsTestingBackface) { if ((p_stGlobaleMT -> lHierachDrawMask & GLI_C_lIsNotDrawingInMirror) ? (p_stGlobaleMT -> lCurrentDrawMask & GLI_C_lNotInvertBackfaces) : !(p_stGlobaleMT -> lCurrentDrawMask & GLI_C_lNotInvertBackfaces) ) { GLI_M_AddFunc(GLI_TestBackfaceClockwise); ulFuncMask |= Flag_GLI_TestBackfaceClockwise; } else { /* reverse */ GLI_M_AddFunc(GLI_TestBackfaceCounterClockwize); ulFuncMask |= Flag_GLI_TestBackfaceCounterClockwize; } } /* ------------------------------------------------------------------------------------*/ /* XY CLIPPING..*/ /* ------------------------------------------------------------------------------------*/ #define GLI_C_lCUT_ALL (GLI_C_CutMaskXMin | GLI_C_CutMaskXMax | GLI_C_CutMaskYMin | GLI_C_CutMaskYMax ) if (GLI_BIG_GLOBALS -> lClippingModeMask & GLI_C_lCUT_ALL) { switch (GLI_BIG_GLOBALS -> lClippingModeMask & (GLI_C_CutMaskXMin | GLI_C_CutMaskXMax )) { case 0:break; case GLI_C_CutMaskXMin + GLI_C_CutMaskXMax:GLI_M_AddFunc(GLI_XMaxCLipping); ulFuncMask |= Flag_GLI_XMaxCLipping; /* STM - fallthrough - was already here*/ case GLI_C_CutMaskXMin:GLI_M_AddFunc(GLI_XMinCLipping); ulFuncMask |= Flag_GLI_XMinCLipping; break; case GLI_C_CutMaskXMax:GLI_M_AddFunc(GLI_XMaxCLipping); ulFuncMask |= Flag_GLI_XMaxCLipping; break; } switch (GLI_BIG_GLOBALS -> lClippingModeMask & (GLI_C_CutMaskYMin | GLI_C_CutMaskYMax )) { case 0:break; case GLI_C_CutMaskYMin + GLI_C_CutMaskYMax:GLI_M_AddFunc(GLI_YMinCLipping); ulFuncMask |= Flag_GLI_YMinCLipping; /* STM - fallthrough - was already here*/ case GLI_C_CutMaskYMax:GLI_M_AddFunc(GLI_YMaxCLipping); ulFuncMask |= Flag_GLI_YMaxCLipping; break; case GLI_C_CutMaskYMin:GLI_M_AddFunc(GLI_YMinCLipping); ulFuncMask |= Flag_GLI_YMinCLipping; break; } } /* ------------------------------------------------------------------------------------*/ /* COMPUTE COLOR & UVW INIT;*/ /* ------------------------------------------------------------------------------------*/ if (p_stGlobaleMT-> p_stCurrentTexture != NULL) { /* if (GLI_BIG_GLOBALS->lAMirrorIsDetected & 2) { GLI_M_AddFunc(GLI_vComputeMirrorUVW); ulFuncMask |= Flag_GLI_vComputeMirrorUVW; } else */ { if ( p_stGlobaleMT->p_stCurrentTexture->lIncrementIsEnable ) { fAddU = p_stGlobaleMT-> p_stCurrentTexture -> fAddU; fAddV = p_stGlobaleMT-> p_stCurrentTexture -> fAddV; if ((fAddU != 0.0f) || (fAddV != 0.0f)) { GLI_M_AddFunc(GLI_vComputeMovingUVW); ulFuncMask |= Flag_GLI_vComputeMovingUVW; } else { GLI_M_AddFunc(GLI_vComputeNormalUVW); ulFuncMask |= Flag_GLI_vComputeNormalUVW; } } else { GLI_M_AddFunc(GLI_vComputeNormalUVW); ulFuncMask |= Flag_GLI_vComputeNormalUVW; } } /* ------------------------------------------------------------------------------------*/ /* special function for mirror texture*/ /* ------------------------------------------------------------------------------------*/ if (p_stGlobaleMT->p_stCurrentTexture->ucCylingMode & GLI_C_lMirrorU ) GLI_M_AddFunc(GLI_vAlignUForMirrorTexture); if (p_stGlobaleMT->p_stCurrentTexture->ucCylingMode & GLI_C_lMirrorV ) GLI_M_AddFunc(GLI_vAlignVForMirrorTexture); }; /* ------------------------------------------------------------------------------------*/ /* Draw Triangle Func init*/ /* ------------------------------------------------------------------------------------*/ GLI_vAddDrawFunc(); /* ------------------------------------------------------------------------------------*/ /* Add empty func */ /* ------------------------------------------------------------------------------------*/ GLI_M_AddFunc( GLI_fn_LastFunc ); /* ------------------------------------------------------------------------------------*/ /* GO */ /* ------------------------------------------------------------------------------------*/ GLI_BeforeDraw(); { p_stCurrentTriangle = p_stLocalElementIndexedTriangle -> d_stListOfFacesTripled; p_stCurrentTriangleUV = p_stLocalElementIndexedTriangle -> d_stListOfFacesTripledIndexUV; xTriangleCounter = p_stLocalElementIndexedTriangle -> xNbFaces; /*{ /* if (xTriangleCounter == 24) { if ( (GLI_BIG_GLOBALS->p_stCurrentTexture) && (strnicmp(GLI_BIG_GLOBALS->p_stCurrentTexture->a255_cFileName + 28, "petard", 6) == 0) ) { long lPointIndex; MTH3D_tdstVector *pstPoint; float dY, dX, dZ; pstPoint = GLI_BIG_GLOBALS->p_stObj->d_stListOfPoints + 53; if (pstPoint->xY < -.5) { lPointIndex = 12; while (lPointIndex--); { dX = 0.005 * pstPoint->xX / (pstPoint->xY + 0.1); pstPoint->xX -= dX; dZ = 0.005 * (pstPoint->xZ - 0.1) / (pstPoint->xY + 0.1); pstPoint->xZ-= dZ; pstPoint->xY += 0.005; pstPoint++; } } } } } */ /* if (ulFuncMask == MaskBigFunc1)*/ /* BigFunc1(xTriangleCounter);*/ /* else */ { /* normal */ while ( xTriangleCounter -- ) { #if !defined(PRESS_DEMO) PRF_MDRV_vSetIndependantVariable( PRF_C_ulIdpDisplayedTriangle , 0 ); #endif /* PRESS_DEMO */ GLI_M_CallFirstFunc(); #if !defined(PRESS_DEMO) if( PRF_MDRV_lGetIndependantVariable( PRF_C_ulIdpDisplayedTriangle ) ) { PRF_MDRV_vIncreaseVariable( PRF_C_ulVarFaces + PRF_MDRV_lGetIndependantVariable( PRF_C_ulIdpDynOrSta ), PRF_C_pvDisplayed, 1 ); PRF_MDRV_vSetIndependantVariable( PRF_C_ulIdpDisplayedFaces, 1 ); } #endif /* PRESS_DEMO */ p_stCurrentTriangle ++; p_stCurrentTriangleUV ++; } } } GLI_AfterDraw(); #ifdef SGL2 GLI_BIG_GLOBALS->lAMirrorIsDetected = AMirrorIsDetectedSave ; #endif } /**********************************************************************************************/ /* Name: GLI_DRV_xSendSpriteToClip_TRIANGLES*/ /* Goal: Clip a sprite and draw it*/ /* Code: Vincent Lhullier*/ /* OPTIMMIZED : No*/ /**********************************************************************************************/ void GLI_DRV_xSendSpriteToClip_TRIANGLES( GLI_tdstAligned2DVector *a4_st2DVertex, GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT) { ACP_tdst2DUVValues stUV[3]; GEO_tdstTripledIndex stTriangle[2] = { {0,1,2}, {3,2,0} }; p_stGlobaleMT->lCurrentDrawMask |= GLI_C_lIsGouraud; GLI_M_ClearFuncList(); /* -----------------------------------------------------------------------------------*/ /* Fog effect*/ /* ------------------------------------------------------------------------------------*/ if (GLI_BIG_GLOBALS->xFogIsOn) GLI_M_AddFunc(GLI_vSetSpecular); /* -----------------------------------------------------------------------------------*/ /* First CullingZ */ /* ------------------------------------------------------------------------------------*/ GLI_M_AddFunc(GLI_FastZCull); GLI_M_AddFunc(GLI_bCullingXYALL); GLI_M_AddFunc(GLI_vZClipping); GLI_M_AddFunc(GLI_XMaxCLipping); GLI_M_AddFunc(GLI_XMinCLipping); GLI_M_AddFunc(GLI_YMaxCLipping); GLI_M_AddFunc(GLI_YMinCLipping); GLI_M_AddFunc(GLI_vComputeNormalUVW); /* ------------------------------------------------------------------------------------*/ /* Draw Triangle Func init*/ /* ------------------------------------------------------------------------------------*/ GLI_vAddDrawFunc(); /* ------------------------------------------------------------------------------------*/ /* Add empty func */ /* ------------------------------------------------------------------------------------*/ GLI_M_AddFunc( GLI_fn_LastFunc ); /* ------------------------------------------------------------------------------------*/ /* GO */ /* ------------------------------------------------------------------------------------*/ GLI_BeforeDraw(); { SetX( CurrentDestXYZ[0], a4_st2DVertex[0].xX ); SetY( CurrentDestXYZ[0], a4_st2DVertex[0].xY ); SetZ( CurrentDestXYZ[0], a4_st2DVertex[0].xOoZ ); SetX( CurrentDestXYZ[1], a4_st2DVertex[1].xX ); SetY( CurrentDestXYZ[1], a4_st2DVertex[1].xY ); SetZ( CurrentDestXYZ[1], a4_st2DVertex[1].xOoZ ); SetX( CurrentDestXYZ[2], a4_st2DVertex[2].xX ); SetY( CurrentDestXYZ[2], a4_st2DVertex[2].xY ); SetZ( CurrentDestXYZ[2], a4_st2DVertex[2].xOoZ ); /* { char cCounter; for ( cCounter = 0; cCounter < 4; cCounter++ ) if ( (a4_st2DVertex[cCounter].xOoZ <= 0) || (a4_st2DVertex[cCounter].xOoZ > 4) ) break; } */ SetPackedColor( CurrentDestXYZ[0], p_stGlobaleMT->ulColorInitForSprite ); SetPackedColor( CurrentDestXYZ[1], p_stGlobaleMT->ulColorInitForSprite ); SetPackedColor( CurrentDestXYZ[2], p_stGlobaleMT->ulColorInitForSprite ); d_stVirtualUV[0] = &stUV[0]; d_stVirtualUV[1] = &stUV[1]; d_stVirtualUV[2] = &stUV[2]; stUV[0].xU = 1.0f; stUV[0].xV = 1.0f; stUV[1].xU = 0.0f; stUV[1].xV = 1.0f; stUV[2].xU = 0.0f; stUV[2].xV = 0.0f; p_stCurrentTriangle = stTriangle; GLI_M_CallFirstFunc(); SetX( CurrentDestXYZ[0], a4_st2DVertex[3].xX); SetY( CurrentDestXYZ[0], a4_st2DVertex[3].xY); SetZ( CurrentDestXYZ[0], a4_st2DVertex[3].xOoZ); SetX( CurrentDestXYZ[1], a4_st2DVertex[2].xX); SetY( CurrentDestXYZ[1], a4_st2DVertex[2].xY); SetZ( CurrentDestXYZ[1], a4_st2DVertex[2].xOoZ); SetX( CurrentDestXYZ[2], a4_st2DVertex[0].xX); SetY( CurrentDestXYZ[2], a4_st2DVertex[0].xY); SetZ( CurrentDestXYZ[2], a4_st2DVertex[0].xOoZ); SetPackedColor( CurrentDestXYZ[0], p_stGlobaleMT->ulColorInitForSprite ); SetPackedColor( CurrentDestXYZ[1], p_stGlobaleMT->ulColorInitForSprite ); SetPackedColor( CurrentDestXYZ[2], p_stGlobaleMT->ulColorInitForSprite ); d_stVirtualUV[0] = &stUV[0]; d_stVirtualUV[1] = &stUV[1]; d_stVirtualUV[2] = &stUV[2]; stUV[0].xU = 1.0f; stUV[0].xV = 0.0f; stUV[1].xU = 0.0f; stUV[1].xV = 0.0f; stUV[2].xU = 1.0f; stUV[2].xV = 1.0f; p_stCurrentTriangle++; GLI_M_CallFirstFunc(); } GLI_AfterDraw(); } /* Only used for tests (infodesign research), because this is definitly NOT optimized. */ void GLI_DRV_xSendSingleTriangleToClip_TRIANGLES( GLI_tdstAligned2DVector *a3_st2DVertex, ACP_tdst2DUVValues *a3_stUV, GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT) { GEO_tdstTripledIndex stTriangle = {0,1,2}; p_stGlobaleMT->lCurrentDrawMask |= GLI_C_lIsGouraud; GLI_M_ClearFuncList(); /* -----------------------------------------------------------------------------------*/ /* Fog effect*/ /* ------------------------------------------------------------------------------------*/ if (GLI_BIG_GLOBALS->xFogIsOn) GLI_M_AddFunc(GLI_vSetSpecular); /* -----------------------------------------------------------------------------------*/ /* First CullingZ */ /* ------------------------------------------------------------------------------------*/ GLI_M_AddFunc(GLI_FastZCull); GLI_M_AddFunc(GLI_bCullingXYALL); GLI_M_AddFunc(GLI_vZClipping); GLI_M_AddFunc(GLI_XMaxCLipping); GLI_M_AddFunc(GLI_XMinCLipping); GLI_M_AddFunc(GLI_YMaxCLipping); GLI_M_AddFunc(GLI_YMinCLipping); GLI_M_AddFunc(GLI_vComputeNormalUVW); /* ------------------------------------------------------------------------------------*/ /* Draw Triangle Func init*/ /* ------------------------------------------------------------------------------------*/ GLI_vAddDrawFunc(); /* ------------------------------------------------------------------------------------*/ /* Add empty func */ /* ------------------------------------------------------------------------------------*/ GLI_M_AddFunc( GLI_fn_LastFunc ); /* ------------------------------------------------------------------------------------*/ /* GO */ /* ------------------------------------------------------------------------------------*/ GLI_BeforeDraw(); { SetX( CurrentDestXYZ[0], a3_st2DVertex[0].xX ); SetY( CurrentDestXYZ[0], a3_st2DVertex[0].xY ); SetZ( CurrentDestXYZ[0], a3_st2DVertex[0].xOoZ ); SetX( CurrentDestXYZ[1], a3_st2DVertex[1].xX ); SetY( CurrentDestXYZ[1], a3_st2DVertex[1].xY ); SetZ( CurrentDestXYZ[1], a3_st2DVertex[1].xOoZ ); SetX( CurrentDestXYZ[2], a3_st2DVertex[2].xX ); SetY( CurrentDestXYZ[2], a3_st2DVertex[2].xY ); SetZ( CurrentDestXYZ[2], a3_st2DVertex[2].xOoZ ); SetPackedColor( CurrentDestXYZ[0], 0xffffffff ); SetPackedColor( CurrentDestXYZ[1], 0xffffffff ); SetPackedColor( CurrentDestXYZ[2], 0xffffffff ); d_stVirtualUV[0] = &a3_stUV[0]; d_stVirtualUV[1] = &a3_stUV[1]; d_stVirtualUV[2] = &a3_stUV[2]; p_stCurrentTriangle = &stTriangle; GLI_M_CallFirstFunc(); } GLI_AfterDraw(); } /**********************************************************************************************/ /* Name: GLI_lCullListOfPoints*/ /* Goal: return 0 if it's sure that this list is invisible*/ /* Code: Philippe Vimont */ /* OPTIMMIZED : No*/ /**********************************************************************************************/ long GLI_lCullListOfPoints (GLD_tdstViewportAttributes *p_stVpt,long lNbPoints,GLI_tdstAligned2DVector *p_st2DVertex) { long CullCounter; GLI_tdstAligned2DVector *p_VertexCmp; *(float *)&fX_CMP_Optimize = 640.0f; *(float *)&fY_CMP_Optimize = 480.0f; p_VertexCmp = p_st2DVertex; CullCounter = 0; p_st2DVertex[8].xX = 320.0f; while ((p_VertexCmp++) -> xX < 0) CullCounter++; if (CullCounter == 8) return 0; p_VertexCmp = p_st2DVertex; CullCounter = 0; while (*(long *)&(p_VertexCmp++)->xX > fX_CMP_Optimize) CullCounter++; if (CullCounter == 8) return 0; p_VertexCmp = p_st2DVertex; CullCounter = 0; p_st2DVertex[8].xY = 240.0f; while ((p_VertexCmp++)->xY < 0) CullCounter++; if (CullCounter == 8) return 0; p_VertexCmp = p_st2DVertex; CullCounter = 0; while (*(long *)&(p_VertexCmp++)->xY > fY_CMP_Optimize) CullCounter++; if (CullCounter == 8) return 0; /* mmmmouais..*/ return (1); } #ifdef __cplusplus } /*extern "C"*/ #endif