//----------------------------------------------------------------------------- // // This file contains texture blending functions. // // Copyright (C) Microsoft Corporation, 1997. // //----------------------------------------------------------------------------- include(`m4hdr.mh')dnl #include "pch.cpp" #pragma hdrstop #include "mtxbd_mh.h" //----------------------------------------------------------------------------- // // TexBlend_Tex1_None // // cPix = cSrc // aPix = aSrc // //----------------------------------------------------------------------------- void CMMX_TexBlend_Tex1_None(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP, PD3DI_RASTSPAN pS) { pCtx->SI.uBB = pS->uB; pCtx->SI.uBG = pS->uG; pCtx->SI.uBR = pS->uR; pCtx->SI.uBA = pS->uA; pCtx->pfnTexBlendEnd(pCtx, pP, pS); } //----------------------------------------------------------------------------- // // TexBlend_Tex1_Decal // // cPix = cTex // aPix = aTex // //----------------------------------------------------------------------------- void CMMX_TexBlend_Tex1_Decal(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP, PD3DI_RASTSPAN pS) { pCtx->SI.uBB = (UINT16)(RGBA_GETBLUE(pCtx->SI.TexCol[0]) << COLOR_SHIFT); pCtx->SI.uBG = (UINT16)(RGBA_GETGREEN(pCtx->SI.TexCol[0])<< COLOR_SHIFT); pCtx->SI.uBR = (UINT16)(RGBA_GETRED(pCtx->SI.TexCol[0]) << COLOR_SHIFT); pCtx->SI.uBA = (UINT16)(RGBA_GETALPHA(pCtx->SI.TexCol[0])<< COLOR_SHIFT); pCtx->pfnTexBlendEnd(pCtx, pP, pS); } //----------------------------------------------------------------------------- // // TexBlend_Tex1_Modulate // // cPix = cSrc * cTex // aPix = aTex // //----------------------------------------------------------------------------- void CMMX_TexBlend_Tex1_Modulate(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP, PD3DI_RASTSPAN pS) { UINT16 uB = pS->uB>>COLOR_SHIFT; UINT16 uG = pS->uG>>COLOR_SHIFT; UINT16 uR = pS->uR>>COLOR_SHIFT; UINT16 uTB = (UINT16)(RGBA_GETBLUE(pCtx->SI.TexCol[0])); UINT16 uTG = (UINT16)(RGBA_GETGREEN(pCtx->SI.TexCol[0])); UINT16 uTR = (UINT16)(RGBA_GETRED(pCtx->SI.TexCol[0])); UINT16 uTA = (UINT16)(RGBA_GETALPHA(pCtx->SI.TexCol[0])); // this is a PMULLW, which works on unsigned 16 bit quantities pCtx->SI.uBB = uB*uTB; pCtx->SI.uBG = uG*uTG; pCtx->SI.uBR = uR*uTR; pCtx->SI.uBA = uTA<pfnTexBlendEnd(pCtx, pP, pS); } //----------------------------------------------------------------------------- // // TexBlend_Tex1_ModulateAlphaOVR // // cPix = cSrc * cTex // aPix = aSrc // //----------------------------------------------------------------------------- void CMMX_TexBlend_Tex1_ModulateAlphaOVR(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP, PD3DI_RASTSPAN pS) { UINT16 uB = pS->uB>>COLOR_SHIFT; UINT16 uG = pS->uG>>COLOR_SHIFT; UINT16 uR = pS->uR>>COLOR_SHIFT; UINT16 uTB = (UINT16)(RGBA_GETBLUE(pCtx->SI.TexCol[0])); UINT16 uTG = (UINT16)(RGBA_GETGREEN(pCtx->SI.TexCol[0])); UINT16 uTR = (UINT16)(RGBA_GETRED(pCtx->SI.TexCol[0])); // this is a PMULLW, which works on unsigned 16 bit quantities pCtx->SI.uBB = uB*uTB; pCtx->SI.uBG = uG*uTG; pCtx->SI.uBR = uR*uTR; pCtx->SI.uBA = pS->uA; pCtx->pfnTexBlendEnd(pCtx, pP, pS); } //----------------------------------------------------------------------------- // // TexBlend_Tex1_Gen // // Calls first set of function pointers to do general texture blending. // //----------------------------------------------------------------------------- void CMMX_TexBlend_Tex1_Gen(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP, PD3DI_RASTSPAN pS) { // Initialize input to diffuse color (the default) D3DI_RASTCOLOR Input = *(D3DI_RASTCOLOR*)&pS->uB; D3DI_RASTCOLOR Arg1; D3DI_RASTCOLOR Arg2; pCtx->pfnTexBlendGetAlpha[0](&Arg1, &Arg2, &Input, pCtx, pS, 0); pCtx->pfnTexBlendOpAlpha[0]((D3DI_RASTCOLOR*)&pCtx->SI.uBB, &Arg1, &Arg2, pCtx, pS, 0); pCtx->pfnTexBlendGetColor[0](&Arg1, &Arg2, &Input, pCtx, pS, 0); pCtx->pfnTexBlendOpColor[0]((D3DI_RASTCOLOR*)&pCtx->SI.uBB, &Arg1, &Arg2, pCtx, pS, 0); pCtx->pfnTexBlendEnd(pCtx, pP, pS); } //----------------------------------------------------------------------------- // // TexBlend_TexM_Gen // // Does general multi-texture blending. // //----------------------------------------------------------------------------- void CMMX_TexBlend_TexM_Gen(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP, PD3DI_RASTSPAN pS) { // Initialize input to diffuse color (the default) D3DI_RASTCOLOR Input0 = *(D3DI_RASTCOLOR*)&pS->uB; D3DI_RASTCOLOR Input1; D3DI_RASTCOLOR Arg1; D3DI_RASTCOLOR Arg2; pCtx->pfnTexBlendGetAlpha[0](&Arg1, &Arg2, &Input0, pCtx, pS, 0); pCtx->pfnTexBlendOpAlpha[0](&Input1, &Arg1, &Arg2, pCtx, pS, 0); pCtx->pfnTexBlendGetColor[0](&Arg1, &Arg2, &Input0, pCtx, pS, 0); pCtx->pfnTexBlendOpColor[0](&Input1, &Arg1, &Arg2, pCtx, pS, 0); pCtx->pfnTexBlendGetAlpha[1](&Arg1, &Arg2, &Input1, pCtx, pS, 1); pCtx->pfnTexBlendOpAlpha[1]((D3DI_RASTCOLOR*)&pCtx->SI.uBB, &Arg1, &Arg2, pCtx, pS, 1); pCtx->pfnTexBlendGetColor[1](&Arg1, &Arg2, &Input1, pCtx, pS, 1); pCtx->pfnTexBlendOpColor[1]((D3DI_RASTCOLOR*)&pCtx->SI.uBB, &Arg1, &Arg2, pCtx, pS, 1); pCtx->pfnTexBlendEnd(pCtx, pP, pS); } dnl dnl d_TexBlendGetAlpha dnl dnl Generates all the differentiated texture alpha blend gets. dnl dnl It takes 2 parameters. dnl dnl $1 is one of TextureAlpha, InvTextureAlpha dnl $2 is one of DiffuseAlpha, InputAlpha, FactorAlpha, InvDiffuseAlpha, InvInputAlpha, InvFactorAlpha dnl dnl Assumes that the Arg1 and Arg2 are 8 bit colors, and that Input is a 8.8. dnl define(`d_TexBlendGetAlpha', `void CMMX_TexBlend_Get_Alpha_$1_$2(PD3DI_RASTCOLOR pArg1, PD3DI_RASTCOLOR pArg2, PD3DI_RASTCOLOR pInput, PD3DI_RASTCTX pCtx, PD3DI_RASTSPAN pS, INT32 iTex) { ifelse(`$1', `TextureAlpha', ` pArg1->uA = (UINT8)RGBA_GETALPHA(pCtx->SI.TexCol[iTex]);', `$1', `InvTextureAlpha', ` pArg1->uA = (UINT8)~(RGBA_GETALPHA(pCtx->SI.TexCol[iTex]));') dnl ifelse(`$2', `DiffuseAlpha', ` pArg2->uA = (UINT8)(pS->uA>>COLOR_SHIFT);', `$2', `InputAlpha', ` pArg2->uA = (UINT8)(pInput->uA>>COLOR_SHIFT);', `$2', `FactorAlpha', ` pArg2->uA = (UINT8)RGBA_GETALPHA(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]);', `$2', `InvDiffuseAlpha', ` pArg2->uA = (UINT8)~((pS->uA>>COLOR_SHIFT));', `$2', `InvInputAlpha', ` pArg2->uA = (UINT8)~((pInput->uA>>COLOR_SHIFT));', `$2', `InvFactorAlpha', ` pArg2->uA = (UINT8)~(RGBA_GETALPHA(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]));') } ') dnl d_RepStr(`d_RepStr(`d_TexBlendGetAlpha(AA, BB)', `AA', TextureAlpha, InvTextureAlpha)', `BB', DiffuseAlpha, InputAlpha, FactorAlpha, InvDiffuseAlpha, InvInputAlpha, InvFactorAlpha) dnl dnl dnl d_TexBlendOpAlpha dnl dnl Generates all the differentiated texture alpha operations. dnl dnl It takes 1 parameter. dnl dnl $1 is one of None, Copy, Modulate, Modulate2, Modulate4, Add, AddSigned, BlendDiffuseAlpha, BlendTextureAlpha, BlendFactorAlpha dnl dnl Assumes that the Arg1 and Arg2 are 8 bit colors. Produces 8.8 output. dnl define(`d_TexBlendOpAlpha', `void CMMX_TexBlend_Op_Alpha_$1(PD3DI_RASTCOLOR pOut, PD3DI_RASTCOLOR pArg1, PD3DI_RASTCOLOR pArg2, PD3DI_RASTCTX pCtx, PD3DI_RASTSPAN pS, INT32 iTex) { ifelse(`$1', `None', ` pOut->uA = pS->uA;', `$1', `CopyArg1', ` pOut->uA = pArg1->uA<uA = pArg2->uA<uA = pArg1->uA*pArg2->uA;', `$1', `Modulate2', ` pOut->uA = min(((UINT32)pArg1->uA*pArg2->uA)<<1, 0xffff);', `$1', `Modulate4', ` pOut->uA = min(((UINT32)pArg1->uA*pArg2->uA)<<2, 0xffff);', `$1', `Add', ` pOut->uA = min(((UINT32)pArg1->uA+pArg2->uA)<uA = (min(max((INT32)pArg1->uA+pArg2->uA-128, 0x0), 0xff))<uA>>COLOR_SHIFT; pOut->uA = (UINT16)(iA*(pArg1->uA - pArg2->uA) + (pArg2->uA<SI.TexCol[iTex]); pOut->uA = (UINT16)(iA*(pArg1->uA - pArg2->uA) + (pArg2->uA<pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]); pOut->uA = (UINT16)(iA*(pArg1->uA - pArg2->uA) + (pArg2->uA<SI.TexCol[iTex]); pOut->uA = min((UINT32)((pArg1->uA<uA), 0xffff);') } ') dnl dnl d_RepStr(`d_TexBlendOpAlpha(AA)', `AA', None, CopyArg1, CopyArg2, Modulate, Modulate2, Modulate4, Add, AddSigned, BlendDiffuseAlpha, BlendTextureAlpha, BlendFactorAlpha, BlendTextureAlphaPM) dnl dnl d_TexBlendGetColor dnl dnl Generates all the differentiated texture color blend gets. dnl dnl It takes 2 parameters. dnl dnl $1 is one of Texure, InvTexture, TextureAlpha, InvTextureAlpha dnl $2 is one of DiffuseAlpha, InputAlpha, FactorAlpha, InvDiffuseAlpha, InvInputAlpha, InvFactorAlpha dnl dnl Assumes that the Arg1 and Arg2 are 8 bit colors, and that Input is a 8.8. dnl define(`d_TexBlendGetColor', `void CMMX_TexBlend_Get_Color_$1_$2(PD3DI_RASTCOLOR pArg1, PD3DI_RASTCOLOR pArg2, PD3DI_RASTCOLOR pInput, PD3DI_RASTCTX pCtx, PD3DI_RASTSPAN pS, INT32 iTex) { ifelse(`$1', `Texture', ` pArg1->uB = (UINT8)RGBA_GETBLUE(pCtx->SI.TexCol[iTex]); pArg1->uG = (UINT8)RGBA_GETGREEN(pCtx->SI.TexCol[iTex]); pArg1->uR = (UINT8)RGBA_GETRED(pCtx->SI.TexCol[iTex]);', `$1', `InvTexture', ` pArg1->uB = (UINT8)~(RGBA_GETBLUE(pCtx->SI.TexCol[iTex])); pArg1->uG = (UINT8)~(RGBA_GETGREEN(pCtx->SI.TexCol[iTex])); pArg1->uR = (UINT8)~(RGBA_GETRED(pCtx->SI.TexCol[iTex]));', `$1', `TextureAlpha', ` pArg1->uB = (UINT8)RGBA_GETALPHA(pCtx->SI.TexCol[iTex]); pArg1->uG = pArg1->uB; pArg1->uR = pArg1->uB;', `$1', `InvTextureAlpha', ` pArg1->uB = (UINT8)~(RGBA_GETALPHA(pCtx->SI.TexCol[iTex])); pArg1->uG = pArg1->uB; pArg1->uR = pArg1->uB;') dnl ifelse(`$2', `Diffuse', ` pArg2->uB = (UINT8)(pS->uB>>COLOR_SHIFT); pArg2->uG = (UINT8)(pS->uG>>COLOR_SHIFT); pArg2->uR = (UINT8)(pS->uR>>COLOR_SHIFT);', `$2', `Input', ` pArg2->uB = (UINT8)(pInput->uB>>COLOR_SHIFT); pArg2->uG = (UINT8)(pInput->uG>>COLOR_SHIFT); pArg2->uR = (UINT8)(pInput->uR>>COLOR_SHIFT);', `$2', `Factor', ` pArg2->uB = (UINT8)RGBA_GETBLUE(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]); pArg2->uG = (UINT8)RGBA_GETGREEN(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]); pArg2->uR = (UINT8)RGBA_GETRED(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]);', `$2', `InvDiffuse', ` pArg2->uB = (UINT8)~((pS->uB>>COLOR_SHIFT)); pArg2->uG = (UINT8)~((pS->uG>>COLOR_SHIFT)); pArg2->uR = (UINT8)~((pS->uR>>COLOR_SHIFT));', `$2', `InvInput', ` pArg2->uB = (UINT8)~((pInput->uB>>COLOR_SHIFT)); pArg2->uG = (UINT8)~((pInput->uG>>COLOR_SHIFT)); pArg2->uR = (UINT8)~((pInput->uR>>COLOR_SHIFT));', `$2', `InvFactor', ` pArg2->uB = (UINT8)~(RGBA_GETBLUE(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR])); pArg2->uG = (UINT8)~(RGBA_GETGREEN(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR])); pArg2->uR = (UINT8)~(RGBA_GETRED(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]));', `$2', `DiffuseAlpha', ` pArg2->uB = (UINT8)(pS->uA>>COLOR_SHIFT); pArg2->uG = pArg2->uB; pArg2->uR = pArg2->uB;', `$2', `InputAlpha', ` pArg2->uB = (UINT8)(pInput->uA>>COLOR_SHIFT); pArg2->uG = pArg2->uB; pArg2->uR = pArg2->uB;', `$2', `FactorAlpha', ` pArg2->uB = (UINT8)RGBA_GETALPHA(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]); pArg2->uG = pArg2->uB; pArg2->uR = pArg2->uB;', `$2', `InvDiffuseAlpha', ` pArg2->uB = (UINT8)~((pS->uA>>COLOR_SHIFT)); pArg2->uG = pArg2->uB; pArg2->uR = pArg2->uB;', `$2', `InvInputAlpha', ` pArg2->uB = (UINT8)~((pInput->uA>>COLOR_SHIFT)); pArg2->uG = pArg2->uB; pArg2->uR = pArg2->uB;', `$2', `InvFactorAlpha', ` pArg2->uB = (UINT8)~(RGBA_GETALPHA(pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR])); pArg2->uG = pArg2->uB; pArg2->uR = pArg2->uB;') } ') dnl d_RepStr(`d_RepStr(`d_TexBlendGetColor(AA, BB)', `AA', Texture, InvTexture, TextureAlpha, InvTextureAlpha)', `BB', Diffuse, Input, Factor, InvDiffuse, InvInput, InvFactor, DiffuseAlpha, InputAlpha, FactorAlpha, InvDiffuseAlpha, InvInputAlpha, InvFactorAlpha) dnl dnl dnl d_TexBlendOpColor dnl dnl Generates all the differentiated texture color operations. dnl dnl It takes 1 parameter. dnl dnl $1 is one of None, Copy, Modulate, Modulate2, Modulate4, Add, AddSigned, BlendDiffuseAlpha, BlendTextureAlpha, BlendFactorAlpha dnl dnl Assumes that the inputs are 8 bit colors. dnl define(`d_TexBlendOpColor', `void CMMX_TexBlend_Op_Color_$1(PD3DI_RASTCOLOR pOut, PD3DI_RASTCOLOR pArg1, PD3DI_RASTCOLOR pArg2, PD3DI_RASTCTX pCtx, PD3DI_RASTSPAN pS, INT32 iTex) { ifelse(`$1', `None', ` pOut->uB = pS->uB; pOut->uG = pS->uG; pOut->uR = pS->uR;', `$1', `CopyArg1', ` pOut->uB = pArg1->uB<uG = pArg1->uG<uR = pArg1->uR<uB = pArg2->uB<uG = pArg2->uG<uR = pArg2->uR<uB = pArg1->uB*pArg2->uB; pOut->uG = pArg1->uG*pArg2->uG; pOut->uR = pArg1->uR*pArg2->uR;', `$1', `Modulate2', ` pOut->uB = min(((UINT32)pArg1->uB*pArg2->uB)<<1, 0xffff); pOut->uG = min(((UINT32)pArg1->uG*pArg2->uG)<<1, 0xffff); pOut->uR = min(((UINT32)pArg1->uR*pArg2->uR)<<1, 0xffff);', `$1', `Modulate4', ` pOut->uB = min(((UINT32)pArg1->uB*pArg2->uB)<<2, 0xffff); pOut->uG = min(((UINT32)pArg1->uG*pArg2->uG)<<2, 0xffff); pOut->uR = min(((UINT32)pArg1->uR*pArg2->uR)<<2, 0xffff);', `$1', `Add', ` pOut->uB = min(((UINT32)pArg1->uB+pArg2->uB)<uG = min(((UINT32)pArg1->uG+pArg2->uG)<uR = min(((UINT32)pArg1->uR+pArg2->uR)<uB = (min(max((INT32)pArg1->uB+pArg2->uB-128, 0x0), 0xff))<uG = (min(max((INT32)pArg1->uG+pArg2->uG-128, 0x0), 0xff))<uR = (min(max((INT32)pArg1->uR+pArg2->uR-128, 0x0), 0xff))<uA>>COLOR_SHIFT; pOut->uB = (UINT16)(iA*(pArg1->uB - pArg2->uB) + (pArg2->uB<uG = (UINT16)(iA*(pArg1->uG - pArg2->uG) + (pArg2->uG<uR = (UINT16)(iA*(pArg1->uR - pArg2->uR) + (pArg2->uR<SI.TexCol[iTex]); pOut->uB = (UINT16)(iA*(pArg1->uB - pArg2->uB) + (pArg2->uB<uG = (UINT16)(iA*(pArg1->uG - pArg2->uG) + (pArg2->uG<uR = (UINT16)(iA*(pArg1->uR - pArg2->uR) + (pArg2->uR<pdwRenderState[D3DRENDERSTATE_TEXTUREFACTOR]); pOut->uB = (UINT16)(iA*(pArg1->uB - pArg2->uB) + (pArg2->uB<uG = (UINT16)(iA*(pArg1->uG - pArg2->uG) + (pArg2->uG<uR = (UINT16)(iA*(pArg1->uR - pArg2->uR) + (pArg2->uR<SI.TexCol[iTex]); pOut->uB = min((UINT32)((pArg1->uB<uB), 0xffff); pOut->uG = min((UINT32)((pArg1->uG<uG), 0xffff); pOut->uR = min((UINT32)((pArg1->uR<uR), 0xffff);') } ') dnl dnl d_RepStr(`d_TexBlendOpColor(AA)', `AA', None, CopyArg1, CopyArg2, Modulate, Modulate2, Modulate4, Add, AddSigned, BlendDiffuseAlpha, BlendTextureAlpha, BlendFactorAlpha, BlendTextureAlphaPM)