/******************************************************************************************
FILE : DoMat Glide2

  Do render parameters settings for texture/material/fog
  Dispay black triangles for window smaller than screen
      
*******************************************************************************************/

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#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 "TEX.h"
#include "light.h"
#include "GliBench.h"

#include "DLLCom.h"
#include "PRF.h"

#include <gl/gl.h>

#include "OGL_Options.h"
#include "OGL_Errors.h"
#include "OGL_Thread.h"

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#ifdef __cplusplus
extern "C" 
{
#endif

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*
 =======================================================================================
    Globals 
 =======================================================================================
 */

/*typedef struct _GLI_tdScreenVertx {
        float sx;  
        float sy;
		float sz;
		//float rhw; 
		unsigned long color;  
		unsigned long specular;   
		float tu;  
		float tv;
} GLI_tdScreenVertx;
*/

/*
 * render parameters
 */
static long             bIsWriteEnable = 1;
static ACP_tdxIndex     xSaveFogIsOn = 0;
static unsigned char    ucSaveCyclingMode = -1;
static unsigned char    ucSaveFunction = -1;
static unsigned long    gs_ulDepthBufferTestEnabled = 0;

/*
 *  Fog table
 */
//GrFog_t                 Gli_C_xFogTable[ GR_FOG_TABLE_SIZE ];
//float                   GLI_ga_fFogDist[ GR_FOG_TABLE_SIZE ];

/*
 * Black triangles
 */
GLI_tdScreenVertx                g_stBlackTriangle[16];
long                    g_lNumberOfBlackTriangles = 0;

/*
 * external
 */
//extern long             g_lDestWidth, g_lDestHeight;


/*
 =======================================================================================
    Special function for displaying black polygon
        it's for cinematic scene to hide non black for color
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : reinit list of black triangles
 ----------------------------------------------------------------------------------------
 */
void GLI_DRV_vNoBlackPolygon()
{
    g_lNumberOfBlackTriangles = 0;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Add a black triangles to list
  Assume that list is large enough (no test)
 ----------------------------------------------------------------------------------------
 */
void GLI_DRV_vAddBlackPolygon( long _lLeft, long _lTop, long _lRight, long _lBottom )
{

    GLI_tdScreenVertx *p_stVertex;

    p_stVertex = g_stBlackTriangle + g_lNumberOfBlackTriangles;
    memset( p_stVertex, 0, 4 * sizeof( GLI_tdScreenVertx ) );
    g_lNumberOfBlackTriangles += 4;

    p_stVertex->sx   = (float) _lLeft;
    p_stVertex->sy   = (float) _lBottom;
    p_stVertex->sz = .8f;

    p_stVertex++;
    p_stVertex->sx   = (float) _lLeft;
    p_stVertex->sy   = (float) _lTop;
    p_stVertex->sz = .8f;

    p_stVertex++;
    p_stVertex->sx   = (float) _lRight;
    p_stVertex->sy   = (float) _lTop;
    p_stVertex->sz = .8f;

    p_stVertex++;
    p_stVertex->sx   = (float) _lRight;
    p_stVertex->sy   = (float) _lBottom;
    p_stVertex->sz = .8f;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Draw black triangles
 ----------------------------------------------------------------------------------------
 */
void GLI_vSendBlackPolygon()
{
    if (g_lNumberOfBlackTriangles == 0)
        return;

    xSaveFogIsOn = 0;	
	OGLThread_fn_vPostCmd(OGLT0_BLACKPOLY);
}

/*
 =======================================================================================
    Function for Fog
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : Set render parameter for given fog parameters
 ----------------------------------------------------------------------------------------
 */

tdstFogParams* g_p_stFogParams;

void GLI_vSetFogParams( tdstFogParams *_p_stFogParams )
{
	g_p_stFogParams = _p_stFogParams;
	OGLThread_fn_vPostCmd(OGLT0_FOGPARAM);
}


/*
 ----------------------------------------------------------------------------------------
  Description   : compute fog effect on vertex color (nothing to do for Glide2)
 ----------------------------------------------------------------------------------------
 */
void GLI_DRV_vComputeFogEffect(GLI_tdstInternalGlobalValuesFor3dEngine *p_stBG )
{
}

/*
 =======================================================================================
    ZBuffer function
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : To enable write to ZBuffer
 ----------------------------------------------------------------------------------------
 */
static void GLI_fn_vEnableWriteToZBuffer()
{
    if (bIsWriteEnable) 
        return;
	OGLThread_fn_vPostCmd_1Long(OGLT1_DEPTHMASK, (long)GL_TRUE);
    bIsWriteEnable = 1;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : To disable write to ZBuffer
 ----------------------------------------------------------------------------------------
 */
static void GLI_fn_vDisableWriteToZBuffer()
{
    if (!bIsWriteEnable) 
        return;
	OGLThread_fn_vPostCmd_1Long(OGLT1_DEPTHMASK, (long)GL_FALSE);
    bIsWriteEnable = 0;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : To manage use of ZBuffer
 ----------------------------------------------------------------------------------------
 */

void GLI_DRV_vEnableDepthTest()
{
    if( gs_ulDepthBufferTestEnabled )
        return;

    OGLThread_fn_vPostCmd_1Long( OGLT1_ENABLE, GL_DEPTH_TEST);
    gs_ulDepthBufferTestEnabled = 1;
}

void GLI_DRV_vDisableDepthTest()
{
    if( ! gs_ulDepthBufferTestEnabled )
        return;

    OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_DEPTH_TEST);
    gs_ulDepthBufferTestEnabled = 0;
}

/*
 =======================================================================================
    Main render parameter setting functions
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : Macro to set chromakey
         CB : La valeur de chromakey doit etre égale à : 5 bits de poids fort, plus les 3 bits de poids fort copiés dans les bits de poids faible.... !!!
         VL : sauf pour la composante G : 6 bit de poids fort + 2 bit de poids fort copiés dans les bits de poids faible !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 ----------------------------------------------------------------------------------------
 */
#define M_vChromakey()\
    if (p_stGlobaleMT -> p_stCurrentTexture -> lTextureCaps & GLI_C_lNZTexture)\
    {\
        unsigned long ulChromakey;\
		grChromakeyMode( GR_CHROMAKEY_ENABLE );\
        ulChromakey = (p_stGlobaleMT->p_stCurrentTexture->lChromakeyColorRGBA & 0x00F800F8) | ((p_stGlobaleMT->p_stCurrentTexture->lChromakeyColorRGBA & 0x00E000E0) >> 5);\
        ulChromakey|= (p_stGlobaleMT->p_stCurrentTexture->lChromakeyColorRGBA & 0x0000FC00) | ((p_stGlobaleMT->p_stCurrentTexture->lChromakeyColorRGBA & 0x0000C000) >> 6);\
        grChromakeyValue( ulChromakey );\
    }\
    else\
    {\
        grChromakeyMode( GR_CHROMAKEY_DISABLE );\
    }

/*
 ----------------------------------------------------------------------------------------
  Description   : Macro to change fog rendering
 ----------------------------------------------------------------------------------------
 */
#define M_vFog()\
    if (GLI_BIG_GLOBALS->xFogIsOn)\
    {\
        if ( GLI_BIG_GLOBALS->p_stLastComputedFog != GLI_BIG_GLOBALS->p_stActiveFog )\
        {\
            GLI_vSetFogParams( GLI_BIG_GLOBALS->p_stActiveFog );\
            GLI_BIG_GLOBALS->p_stLastComputedFog = GLI_BIG_GLOBALS->p_stActiveFog;\
        }\
        if (!xSaveFogIsOn)\
        {\
            OGLThread_fn_vPostCmd_1Long( OGLT1_ENABLE, GL_FOG); /*grFogMode( GR_FOG_WITH_TABLE);*/\
            xSaveFogIsOn = 1;\
        }\
    }\
    else if (xSaveFogIsOn)\
    {\
        OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_FOG); /*grFogMode( GR_FOG_DISABLE);*/\
        xSaveFogIsOn = 0;\
    }
 


/*
 ----------------------------------------------------------------------------------------
  Description   : Set init parameter as none set
 ----------------------------------------------------------------------------------------
 */
void GLI_fn_vInitRenderParameters( void )
{
    bIsWriteEnable = 1;
    xSaveFogIsOn = 0;
//    xSaveTmuNumber = -1;
    ucSaveCyclingMode = -1;
    ucSaveFunction = -1;
	OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_ALPHA_TEST);
	OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_FOG); 
}

/*
 ----------------------------------------------------------------------------------------
  Description   : set render parameters that will work for all faces which are not 
                  transparent
 ----------------------------------------------------------------------------------------
 */
void GLI_fn_vSetRenderParametersBeforeOpaqueFace( void ) {
  
  //grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,GR_COMBINE_FACTOR_ONE,GR_COMBINE_LOCAL_NONE,GR_COMBINE_OTHER_TEXTURE,FXFALSE);
  //grAlphaTestFunction( GR_CMP_ALWAYS );
  //grAlphaTestReferenceValue( 0xC0 );
  
  OGLThread_fn_vPostCmd_2Long( OGLT2_BLENDFUNC, GL_ONE, GL_ZERO); //grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO);
  OGLThread_fn_vPostCmd_1Long( OGLT1_TEXTUREENV, GL_MODULATE); // guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB);

  ucSaveFunction = 4;
  OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_ALPHA_TEST); // ?
    
  GLI_fn_vEnableWriteToZBuffer();
}

/*
 ----------------------------------------------------------------------------------------
  Description   : called before the rendering of any triangle
 ----------------------------------------------------------------------------------------
 */
BOOL GLI_DRV_bBeginScene()
{
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : called after the rendering of all triangles
 ----------------------------------------------------------------------------------------
 */
BOOL GLI_DRV_bEndScene()
{
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Called for all object before drawn. 
                Set some general parameters and set render parameter for opaque texture only
 ----------------------------------------------------------------------------------------
 */
void GLI_DRV_vDoOpaqueTextureSelection(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT)
{
	GLboolean bOK;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//    GLI_tdstTextureDFX      *p_stSpecParam;
    BOOL                    bTexture;
#if defined (TEX_TEST)
	BOOL bTempOk;
	unsigned int		uiTextureId;
#endif //defined (TEX_TEST)
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


    if (*GLD_p_lRenderingCounter != p_stGlobaleMT->GLD_RenderingCounter)
    {
        p_stGlobaleMT->GLD_RenderingCounter = *GLD_p_lRenderingCounter;
        GLI_vSendBlackPolygon();

		// GLI_fn_vSetRenderParametersBeforeOpaqueFace() :
        /*
        grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO);
        grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,GR_COMBINE_FACTOR_ONE,GR_COMBINE_LOCAL_NONE,GR_COMBINE_OTHER_TEXTURE,FXFALSE);
        guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB);
        grAlphaTestFunction( GR_CMP_ALWAYS );
        grAlphaTestReferenceValue( 0xC0 );
		*/
		OGLThread_fn_vPostCmd_2Long( OGLT2_BLENDFUNC, GL_ONE, GL_ZERO);
		OGLThread_fn_vPostCmd_1Long( OGLT1_TEXTUREENV, GL_MODULATE); 
        
		ucSaveFunction = 4;
		OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_ALPHA_TEST);
    }


	GLI_fn_vEnableWriteToZBuffer();
    if ( p_stGlobaleMT->lCurrentDrawMask & GLI_C_lIsEnableZSorting )
        GLI_DRV_vEnableDepthTest();
    else
        GLI_DRV_vDisableDepthTest();

    bTexture = (p_stGlobaleMT->p_stCurrentTexture != NULL) && (p_stGlobaleMT->p_stCurrentTexture->bIsAvailable);

    /*
     * test if triangle will be transparent if so do not set render parameters
     */
	if (GLI_BIG_GLOBALS->lAMirrorIsDetected)
		GLI_BIG_GLOBALS->lAMirrorIsDetected = 3;


    if ( 
            ( !(GLI_BIG_GLOBALS->lAMirrorIsDetected) && bTexture && (p_stGlobaleMT -> p_stCurrentTexture -> lTextureCaps & (GLI_C_lAlphaTexture | GLI_C_lNZFilteredTexture | GLI_C_lAddTransparencyTexture) ) )
         || (!(p_stGlobaleMT -> lCurrentDrawMask & GLI_C_lIsNotGrided) && (p_stGlobaleMT->xGlobalAlpha < 0.98f))
       )
    {
        p_stGlobaleMT -> lClippingModeMask |= GLI_C_TrianglesMustBeSorted;
        return;
    }

    
    p_stGlobaleMT -> lClippingModeMask &= 0xffffffff - GLI_C_TrianglesMustBeSorted;

    /*
     * fog
     */
#if !defined(NO_FOG)
	M_vFog();
#endif
    
#ifdef TEX_TEST
	if (bTexture) {
		uiTextureId = (unsigned int) p_stGlobaleMT->p_stCurrentTexture->p_stSpecParam;

		bTempOk = OGLThread_fn_bPostCmdAndWait(OGLT1_ISTEXTURE, (long)uiTextureId);
		if (!bTempOk )
			bTexture = FALSE;
		
		if (bTexture) {
			bTempOk = OGLThread_fn_bPostCmdAndWait(OGLT1_ISRESIDENT, (long)uiTextureId);
			if (!bTempOk)
				bTexture = FALSE;
		}

		// if not resident => delete it
		if (!bTexture) {
			bTempOk = OGLThread_fn_bPostCmdAndWait(OGLT1_ISTEXTURE, (long)uiTextureId);
			if (bTempOk)
				OGLThread_fn_vPostCmd_1Long(OGLT1_DELETETEXTURE, (long)uiTextureId);
		}
	}
#endif //defined (TEX_TEST)

	if ( bTexture )
    {
		
        if (p_stGlobaleMT -> p_stCurrentTexture -> lTextureCaps & GLI_C_lAlphaTest)
        {
            if (ucSaveFunction != 5)
            {
				if ( ucSaveFunction == 2 )
					GLI_fn_vSetRenderParametersBeforeOpaqueFace() ;				
				/*
                grAlphaTestFunction( GR_CMP_GEQUAL );
                guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB);
				*/
				OGLThread_fn_vPostCmd( OGLT0_ALPHATEST );
				OGLThread_fn_vPostCmd_1Long( OGLT1_TEXTUREENV, GL_MODULATE);
 
                ucSaveFunction = 5;
				OGLThread_fn_vPostCmd_1Long( OGLT1_ENABLE, GL_ALPHA_TEST);
            }
        }
        else if (GLI_BIG_GLOBALS->lAMirrorIsDetected & 2)
		{
			/*
			grAlphaBlendFunction( GR_BLEND_SRC_ALPHA,GR_BLEND_ONE_MINUS_SRC_ALPHA,GR_BLEND_ONE ,GR_BLEND_ZERO );
			guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB);
			grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,GR_COMBINE_FACTOR_LOCAL,GR_COMBINE_LOCAL_ITERATED,GR_COMBINE_OTHER_TEXTURE,FXFALSE);
			*/
			OGLThread_fn_vPostCmd_2Long( OGLT2_BLENDFUNC, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			OGLThread_fn_vPostCmd_1Long( OGLT1_TEXTUREENV, GL_MODULATE);

			ucSaveFunction = 2;
			OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_ALPHA_TEST);
		}
		else 
        {
			if (ucSaveFunction != 4)
            {
				if ( ucSaveFunction == 2 )
					GLI_fn_vSetRenderParametersBeforeOpaqueFace() ;				
                /*
				grAlphaTestFunction( GR_CMP_ALWAYS );
                guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB);
				*/
				OGLThread_fn_vPostCmd_1Long( OGLT1_TEXTUREENV, GL_MODULATE);

                ucSaveFunction = 4;
				OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_ALPHA_TEST);
            }
        }

        /*
         * Chromakey
         */
/*            M_vChromakey();*/

		 /*
         * uv cycling mode => made when loading texture
         */

		/*if (p_stGlobaleMT -> p_stCurrentTexture -> lTextureCaps & GLI_C_lNZTexture)
			OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_TEXTURE_2D);
		else*/
		{
			OGLThread_fn_vPostCmd_1Long( OGLT1_ENABLE, GL_TEXTURE_2D);
			OGLThread_fn_vPostCmd_1Long( OGLT1_BINDTEXTURE, (long)p_stGlobaleMT->p_stCurrentTexture->p_stSpecParam );
		}
    }
	else /* gouraud */
    {
		bOK = OGLThread_fn_bPostCmdAndWait(OGLT1_ISENABLED, GL_TEXTURE_2D);
		if (bOK)
		{
			OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_TEXTURE_2D);
			bOK = OGLThread_fn_bPostCmdAndWait(OGLT1_ISENABLED, GL_TEXTURE_2D);
		}
		if (bOK) // still Enabled !
			OGLThread_fn_vPostCmd_1Long( OGLT1_BINDTEXTURE, 0L );

		if (ucSaveFunction != 0)
        {
			/*
                grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO);
                grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,GR_COMBINE_FACTOR_ONE,GR_COMBINE_LOCAL_NONE,GR_COMBINE_OTHER_TEXTURE,FXFALSE);
                grAlphaTestFunction( GR_CMP_ALWAYS );
                guColorCombineFunction( GR_COLORCOMBINE_ITRGB );
                ucSaveFunction = 0;
			*/
			OGLThread_fn_vPostCmd_2Long( OGLT2_BLENDFUNC, GL_ONE, GL_ZERO);
			OGLThread_fn_vPostCmd_1Long( OGLT1_TEXTUREENV, GL_MODULATE);

            ucSaveFunction = 0;
			OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_ALPHA_TEST);
        }
    }
}


/*
 ----------------------------------------------------------------------------------------
  Description   : set render parameters that will work for all transparency faces
 ----------------------------------------------------------------------------------------
 */
void GLI_fn_vSetRenderParametersBeforeTransparencyFace( void )
{
//	grAlphaTestFunction( GR_CMP_ALWAYS );
	GLI_fn_vDisableWriteToZBuffer();
}


/*
 ----------------------------------------------------------------------------------------
  Description   : set render parameters for transparent triangles
 ----------------------------------------------------------------------------------------
 */
void GLI_vDoTransparentTextureSelection(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT)
{
    BOOL                    bTexture;
#ifdef TEX_TEST
	BOOL bTempOk;
	unsigned int		uiTextureId;
#endif //defined (TEX_TEST)
    //grAlphaTestFunction( GR_CMP_ALWAYS );

    /*
     * write to Z buffer ?
     */
	/*
	if (p_stGlobaleMT -> lCurrentDrawMask & GLI_C_lIsWriteZBuffer)
        GLI_fn_vEnableWriteToZBuffer();
    else
        GLI_fn_vDisableWriteToZBuffer();
		*/

    if ( p_stGlobaleMT->lCurrentDrawMask & GLI_C_lIsEnableZSorting )
        GLI_DRV_vEnableDepthTest();
    else
        GLI_DRV_vDisableDepthTest();

    /*
     * fog
     */
#if !defined(NO_FOG)
	M_vFog();
#endif
    
	bTexture = (p_stGlobaleMT -> p_stCurrentTexture != NULL) && (p_stGlobaleMT -> p_stCurrentTexture ->  bIsAvailable);

#ifdef TEX_TEST
	if (bTexture) {
		uiTextureId = (unsigned int) p_stGlobaleMT->p_stCurrentTexture->p_stSpecParam;

		bTempOk = bOGLThread_fn_vPostCmd_WaitForBoolean(OGLT1_ISTEXTURE, (long)uiTextureId);
		if (!bTempOk )
			bTexture = FALSE;
		
		if (bTexture) {
			bTempOk = bOGLThread_fn_vPostCmd_WaitForBoolean(OGLT1_ISRESIDENT, (long)uiTextureId);
			if (!bTempOk)
				bTexture = FALSE;
		}

		// if not resident => delete it
		if (!bTexture) {
			bTempOk = bOGLThread_fn_vPostCmd_WaitForBoolean(OGLT1_ISTEXTURE, (long)uiTextureId);
			if (bTempOk)
				OGLThread_fn_vPostCmd_1Long(OGLT1_DELETETEXTURE, (long)uiTextureId);
		}
	}
#endif //defined (TEX_TEST)

	if (bTexture) //((p_stGlobaleMT -> p_stCurrentTexture != NULL) && (p_stGlobaleMT -> p_stCurrentTexture ->  bIsAvailable))
    {
		//glEnable(GL_TEXTURE_2D);
        if (p_stGlobaleMT -> p_stCurrentTexture -> lTextureCaps & (GLI_C_lAlphaTest | GLI_C_lAlphaTexture | GLI_C_lNZFilteredTexture | GLI_C_lAddTransparencyTexture) )
        {
            if (p_stGlobaleMT -> p_stCurrentTexture -> lTextureCaps & GLI_C_lAddTransparencyTexture)
            {
                // Trans ADD
                if (ucSaveFunction != 1)
                {
                    /*
					grAlphaBlendFunction( GR_BLEND_ONE,GR_BLEND_ONE,GR_BLEND_ZERO ,GR_BLEND_ZERO );
                    guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA);
                    grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,GR_COMBINE_FACTOR_LOCAL,GR_COMBINE_LOCAL_ITERATED,GR_COMBINE_OTHER_TEXTURE,FXFALSE);
					*/
					OGLThread_fn_vPostCmd_2Long( OGLT2_BLENDFUNC, GL_ONE, GL_ONE);
					OGLThread_fn_vPostCmd_1Long( OGLT1_TEXTUREENV, GL_DECAL); // guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA);

                    ucSaveFunction = 1;
					OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_ALPHA_TEST);
                }

                // No fog With This;
                if (xSaveFogIsOn)
                {
                    OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_FOG); //grFogMode( GR_FOG_DISABLE);
                    xSaveFogIsOn = 0;
                }
				
            } 
			else if (ucSaveFunction != 2)
			{
                // Trans ALPHA
                /*
				grAlphaBlendFunction( GR_BLEND_SRC_ALPHA,GR_BLEND_ONE_MINUS_SRC_ALPHA,GR_BLEND_ONE ,GR_BLEND_ZERO );
				guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB);
                grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,GR_COMBINE_FACTOR_LOCAL,GR_COMBINE_LOCAL_ITERATED,GR_COMBINE_OTHER_TEXTURE,FXFALSE);
				*/
				OGLThread_fn_vPostCmd_2Long( OGLT2_BLENDFUNC, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
				OGLThread_fn_vPostCmd_1Long( OGLT1_TEXTUREENV, GL_MODULATE); // guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB);

                ucSaveFunction = 2;
				OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_ALPHA_TEST);
            } 
        } 
        else //if ((!(p_stGlobaleMT -> lCurrentDrawMask & GLI_C_lIsNotGrided)) && (xGlobaLAlpha < 0.98f))
        {
            // Trans ALPHA ITERATED
            if (ucSaveFunction != 3)
            {
                /*
				grAlphaBlendFunction( GR_BLEND_SRC_ALPHA,GR_BLEND_ONE_MINUS_SRC_ALPHA,GR_BLEND_ONE,GR_BLEND_ZERO );
                grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,GR_COMBINE_FACTOR_ONE,GR_COMBINE_LOCAL_ITERATED,GR_COMBINE_OTHER_ITERATED,FXFALSE);
                guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB);
				*/
				OGLThread_fn_vPostCmd_2Long( OGLT2_BLENDFUNC, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
				OGLThread_fn_vPostCmd_1Long( OGLT1_TEXTUREENV, GL_MODULATE); // guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB);

                ucSaveFunction = 3;
				OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_ALPHA_TEST);
            }
        } 

        /*
         * Chromakey
         */
/*            M_vChromakey();*/

         /*
         * uv cycling mode => made when loading texture
         */

		/*if (p_stGlobaleMT -> p_stCurrentTexture -> lTextureCaps & GLI_C_lNZTexture)
			OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_TEXTURE_2D);
		else*/
        {
			OGLThread_fn_vPostCmd_1Long( OGLT1_ENABLE, GL_TEXTURE_2D);
		    OGLThread_fn_vPostCmd_1Long( OGLT1_BINDTEXTURE, (long)p_stGlobaleMT->p_stCurrentTexture->p_stSpecParam );
		}
    } 
	else
    {
        // GOURAUD
		OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_TEXTURE_2D);
        //glBindTexture(GL_TEXTURE_2D, 0 );

        if (((p_stGlobaleMT -> lCurrentDrawMask & GLI_C_lIsNotGrided) == 0) && (p_stGlobaleMT->xGlobalAlpha < 0.98f) )
        {
            // alpha iterated transparency
            /*
			grAlphaBlendFunction( GR_BLEND_SRC_ALPHA,GR_BLEND_ONE_MINUS_SRC_ALPHA,GR_BLEND_ONE,GR_BLEND_ZERO );
            grAlphaCombine(GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_LOCAL_ALPHA,GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE,FXFALSE);
            guAlphaSource(GR_ALPHASOURCE_ITERATED_ALPHA);
			*/
			OGLThread_fn_vPostCmd_2Long( OGLT2_BLENDFUNC, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            p_stGlobaleMT -> lClippingModeMask |= GLI_C_TrianglesMustBeSorted;
        }
        else 
        {
            /*
			grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,GR_COMBINE_FACTOR_ONE,GR_COMBINE_LOCAL_ITERATED,GR_COMBINE_OTHER_ITERATED,FXFALSE);
            grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO);
			*/
			OGLThread_fn_vPostCmd_2Long( OGLT2_BLENDFUNC, GL_ONE, GL_ZERO);
        }
		OGLThread_fn_vPostCmd_1Long( OGLT1_TEXTUREENV, GL_MODULATE); //guColorCombineFunction( GR_COLORCOMBINE_ITRGB );

        ucSaveFunction = 0;
		OGLThread_fn_vPostCmd_1Long( OGLT1_DISABLE, GL_ALPHA_TEST);
    }
}

/*
 =======================================================================================
    Write bitmap into backbuffer 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : write bitmap part into backbuffer
 ----------------------------------------------------------------------------------------
 */
/*
void GLI_fn_vWriteRegion3DFX(long X, long Y, long l, long h, unsigned char *p_ucSrc, long SrcPitch , GrLfbInfo_t *p_info)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*    long lPitch;  
    long *p_sourceptr , *p_sourceptrLast , *p_destptr ,lYCounterLocal;
    short *p_Src;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    
/*    p_Src = (unsigned short *)p_ucSrc;
    lPitch = p_info->strideInBytes/4;
    
    for (lYCounterLocal = 0; lYCounterLocal < h ; lYCounterLocal++)
    {
        p_destptr = ((unsigned long *)p_info->lfbPtr) + (X>>1) + lPitch * (Y + lYCounterLocal);
        p_sourceptr  = ((unsigned long *)p_Src + lYCounterLocal * (SrcPitch >>2)) ;
        p_sourceptrLast = p_sourceptr  + (l>>1);
        for (;p_sourceptr < p_sourceptrLast ;p_sourceptr ++,p_destptr ++)
            *p_destptr = *p_sourceptr ;
    }
}
*/

/*
 ----------------------------------------------------------------------------------------
  Description   : Write a 16 bit bitmap in the back buffer
  _p_vSourceBuffer    -> bitmap
  _lWidth, _lHeight   -> dimension of bitmap
  _lDestX, _lDestY    -> where the bitmap have to be copied in the backbuffer
 ----------------------------------------------------------------------------------------
 */

void* g_p_vSourceBuffer;
RECT g_DestBitmapRect;

void GLI_DRV_vWrite16bBitmapToBackBuffer(  void *_p_vSourceBuffer, long _lWidth, long _lHeight, long _lDestLeft, long _lDestTop, long _lDestRight, long _lDestBottom )
{
	g_p_vSourceBuffer = _p_vSourceBuffer;
	g_DestBitmapRect.left = _lDestLeft;
	g_DestBitmapRect.top = _lDestTop;
	g_DestBitmapRect.right = _lDestRight;
	g_DestBitmapRect.bottom = _lDestBottom;

	OGLThread_fn_vPostCmd_2Long( OGLT2_WRITEBITMAP, _lWidth, _lHeight );
}


#ifdef __cplusplus
} //extern "C"
#endif
