// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stddirect3d.h" #include "driver_direct3d.h" using namespace std; using namespace NLMISC; namespace NL3D { // mem allocator for state records std::allocator CStateRecord::Allocator; // *************************************************************************** // The state manager with cache // *************************************************************************** HRESULT CDriverD3D::QueryInterface(REFIID /* riid */, LPVOID * /* ppvObj */) { H_AUTO_D3D(CDriverD3D_QueryInterface) return D3D_OK; } // *************************************************************************** ULONG CDriverD3D::AddRef(VOID) { H_AUTO_D3D(CDriverD3D_AddRef) return 0; } // *************************************************************************** ULONG CDriverD3D::Release(VOID) { H_AUTO_D3D(CDriverD3D_Release) return 0; } // *************************************************************************** HRESULT CDriverD3D::LightEnable(DWORD Index, BOOL Enable) { H_AUTO_D3D(CDriverD3D_LightEnable) enableLight ((uint8)Index, Enable!=FALSE); return D3D_OK; } // *************************************************************************** HRESULT CDriverD3D::SetFVF(DWORD /* FVF */) { H_AUTO_D3D(CDriverD3D_SetFVF) // Not implemented return D3D_OK; } // *************************************************************************** HRESULT CDriverD3D::SetLight(DWORD Index, CONST D3DLIGHT9* pLight) { H_AUTO_D3D(CDriverD3D_SetLight) _LightCache[Index].Light = *pLight; touchRenderVariable (&_LightCache[Index]); return D3D_OK; } // *************************************************************************** HRESULT CDriverD3D::SetMaterial(CONST D3DMATERIAL9* pMaterial) { H_AUTO_D3D(CDriverD3D_SetMaterial) setMaterialState( *pMaterial ); return D3D_OK; } // *************************************************************************** HRESULT CDriverD3D::SetNPatchMode(FLOAT /* nSegments */) { H_AUTO_D3D(CDriverD3D_SetNPatchMode) // Not implemented return D3D_OK; } // *************************************************************************** HRESULT CDriverD3D::SetPixelShader(LPDIRECT3DPIXELSHADER9 pShader) { H_AUTO_D3D(CDriverD3D_SetPixelShader) setPixelShader (pShader); return D3D_OK; } // *************************************************************************** HRESULT CDriverD3D::SetPixelShaderConstantB(UINT StartRegister, CONST BOOL* pConstantData, UINT RegisterCount) { H_AUTO_D3D(CDriverD3D_SetPixelShaderConstantB) uint i; for (i=0; iRelease(); } // *************************************************************************** bool CDriverD3D::validateShader(CShader *shader) { H_AUTO_D3D(CDriverD3D_validateShader) CShaderDrvInfosD3D *shaderInfo = static_cast((IShaderDrvInfos*)shader->_DrvInfo); if (!shaderInfo->Validated) { // Choose the good method D3DXHANDLE hTechnique = NULL; D3DXHANDLE hCurrentTechnique = NULL; while (hTechnique == NULL) { if (shaderInfo->Effect->FindNextValidTechnique(hCurrentTechnique, &hCurrentTechnique) != D3D_OK) return false; // Info #ifdef NL_FORCE_TEXTURE_STAGE_COUNT D3DXTECHNIQUE_DESC desc; nlverify (shaderInfo->Effect->GetTechniqueDesc(hCurrentTechnique, &desc) == D3D_OK); // Check this is compatible const uint len = strlen(desc.Name); if (len) { char shaderStageCount = desc.Name[len-1]; if ((shaderStageCount>='0') && (shaderStageCount<='9')) { uint stageCount = NL_FORCE_TEXTURE_STAGE_COUNT; if ((uint)(shaderStageCount-'0')<=stageCount) // The good technique hTechnique = hCurrentTechnique; } } #else // NL_FORCE_TEXTURE_STAGE_COUNT hTechnique = hCurrentTechnique; #endif // NL_FORCE_TEXTURE_STAGE_COUNT #ifdef NL_DEBUG_D3D { D3DXTECHNIQUE_DESC desc; nlverify (shaderInfo->Effect->GetTechniqueDesc(hCurrentTechnique, &desc) == D3D_OK); if (hTechnique) nlinfo ("Shader \"%s\" : use technique \"%s\" with %d passes.", shader->getName(), desc.Name, desc.Passes); } #endif // NL_DEBUG_D3D } // Set the technique shaderInfo->Effect->SetTechnique(hTechnique); // Set the state manager shaderInfo->Effect->SetStateManager (this); shaderInfo->Validated = true; } return true; } // *************************************************************************** bool CDriverD3D::activeShader(CShader *shd) { H_AUTO_D3D(CDriverD3D_activeShader) if (_DisableHardwarePixelShader) return false; // Clear current textures _CurrentShaderTextures.clear(); // Shader has been changed ? if (shd && shd->_ShaderChanged) { // Remove old shader shd->_DrvInfo.kill(); // Already setuped ? CShaderDrvInfosD3D *shaderInfo = static_cast((IShaderDrvInfos*)shd->_DrvInfo); if ( !shd->_DrvInfo ) { // insert into driver list. (so it is deleted when driver is deleted). ItShaderDrvInfoPtrList it= _ShaderDrvInfos.insert(_ShaderDrvInfos.end(), NULL); // create and set iterator, for future deletion. shaderInfo = new CShaderDrvInfosD3D(this, it); *it= shd->_DrvInfo = shaderInfo; } // Assemble the shader LPD3DXBUFFER pErrorMsgs; if (D3DXCreateEffect(_DeviceInterface, shd->getText(), (UINT)strlen(shd->getText())+1, NULL, NULL, 0, NULL, &(shaderInfo->Effect), &pErrorMsgs) == D3D_OK) { // Get the texture handle uint i; for (i=0; iTextureHandle[i] = shaderInfo->Effect->GetParameterByName(NULL, name.c_str()); name = "color" + toString (i); shaderInfo->ColorHandle[i] = shaderInfo->Effect->GetParameterByName(NULL, name.c_str()); name = "factor" + toString (i); shaderInfo->FactorHandle[i] = shaderInfo->Effect->GetParameterByName(NULL, name.c_str()); name = "scalarFloat" + toString (i); shaderInfo->ScalarFloatHandle[i] = shaderInfo->Effect->GetParameterByName(NULL, name.c_str()); } } else { nlwarning ("Can't create shader '%s':", shd->getName()); if (pErrorMsgs) nlwarning ((const char*)pErrorMsgs->GetBufferPointer()); shd->_ShaderChanged = false; _CurrentShader = NULL; return false; } // Done shd->_ShaderChanged = false; } // Set the shader _CurrentShader = shd; return true; } static void setFX(CShader &s, const char *name, const char *prog, CDriverD3D *drv) { H_AUTO_D3D(setFX) s.setName(name); s.setText(prog); nlverify (drv->activeShader (&s)); } #define setFx(a,b,c) { setFX(a, b, c, this); } static const char *CloudFx = " \n\ texture texture0; \n\ texture texture1; \n\ float4 factor0; \n\ \n\ pixelshader two_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ lrp r0.w, v0, t0, t1; \n\ mov r0.xyz, c0; \n\ +mul r0.w, c0, r0; \n\ }; \n\ \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ PixelShaderConstant[0] = ; \n\ PixelShader = (two_stages_ps); \n\ } \n\ }; \n\ \n\ "; static const char *Lightmap0Fx = " \n\ texture texture0; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ technique one_stage_1 \n\ { \n\ pass p0 \n\ { \n\ // do a standard lighting with the first light \n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TEXTURE; \n\ ColorArg2[0] = DIFFUSE; \n\ AlphaOp[0] = SELECTARG1; // for alpha test \n\ AlphaArg1[0] = TEXTURE; \n\ } \n\ }; \n\ \n\ "; static const char *Lightmap0blendFx = " \n\ texture texture0; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ technique one_stage_1 \n\ { \n\ pass p0 \n\ { \n\ // do a standard lighting with the first light \n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = SRCALPHA; \n\ DestBlend = INVSRCALPHA; \n\ \n\ Texture[0] = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TEXTURE; \n\ ColorArg2[0] = DIFFUSE; \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TEXTURE; \n\ } \n\ }; \n\ \n\ "; static const char *Lightmap0blend_x2Fx = " \n\ texture texture0; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ technique one_stage_1 \n\ { \n\ pass p0 \n\ { \n\ // do a standard lighting with the first light \n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = SRCALPHA; \n\ DestBlend = INVSRCALPHA; \n\ \n\ Texture[0] = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TEXTURE; \n\ ColorArg2[0] = DIFFUSE; \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TEXTURE; \n\ } \n\ }; \n\ \n\ "; static const char *Lightmap0_x2Fx = " \n\ texture texture0; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ technique one_stage_1 \n\ { \n\ pass p0 \n\ { \n\ // do a standard lighting with the first light \n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TEXTURE; \n\ ColorArg2[0] = DIFFUSE; \n\ AlphaOp[0] = SELECTARG1; // for alpha test \n\ AlphaArg1[0] = TEXTURE; \n\ } \n\ }; \n\ \n\ "; static const char *Lightmap1Fx = " \n\ texture texture0; \n\ texture texture1; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ float4 factor0; \n\ float4 factor1; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; // for alpha test \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ }; \n\ \n\ "; static const char *Lightmap1blendFx = " \n\ texture texture0; \n\ texture texture1; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ float4 factor0; \n\ float4 factor1; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = SRCALPHA; \n\ DestBlend = INVSRCALPHA; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ }; \n\ \n\ "; static const char *Lightmap1blend_x2Fx = " \n\ texture texture0; \n\ texture texture1; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ float4 factor0; \n\ float4 factor1; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ // modulate the dyn light by 0.5, because of MODULATE2X \n\ float4 g_dyn_factor = { 0.5f, 0.5f, 0.5f, 1.0f }; \n\ \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = SRCALPHA; \n\ DestBlend = INVSRCALPHA; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ }; \n\ \n\ "; static const char *Lightmap1_x2Fx = " \n\ texture texture0; \n\ texture texture1; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ float4 factor0; \n\ float4 factor1; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ // modulate the dyn light by 0.5, because of MODULATE2X \n\ float4 g_dyn_factor = { 0.5f, 0.5f, 0.5f, 1.0f }; \n\ \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; // for alpha test \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ }; \n\ \n\ "; static const char *Lightmap2Fx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_ps); \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; // for alpha test \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ } \n\ \n\ "; static const char *Lightmap2blendFx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_ps); \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ } \n\ \n\ \n\ "; static const char *Lightmap2blend_x2Fx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ // modulate the dyn light by 0.5, because of MODULATE2X \n\ float4 g_dyn_factor = { 0.5f, 0.5f, 0.5f, 1.0f }; \n\ \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul_x2 r0.xyz, r0, t0; \n\ mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_ps); \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ } \n\ \n\ \n\ "; static const char *Lightmap2_x2Fx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ // modulate the dyn light by 0.5, because of MODULATE2X \n\ float4 g_dyn_factor = { 0.5f, 0.5f, 0.5f, 1.0f }; \n\ \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul_x2 r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_ps); \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; // for alpha test if enabled \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ } \n\ \n\ "; static const char *Lightmap3Fx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ texture texture3; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ dword color3; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ float4 factor3; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ \n\ // **** 4 stages technique \n\ pixelshader four_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ tex t3; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mad r0.xyz, c3, t3, r0; \n\ mul r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique four_stages_4 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShader = (four_stages_ps); \n\ } \n\ } \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_0_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_0_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ Lighting = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ ColorOp[2] = DISABLE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; // for case when there's alpha test \n\ AlphaOp[2] = DISABLE; \n\ PixelShader = NULL; \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; // alpha in case were alpha test is used\n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ pass p2 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ } \n\ \n\ \n\ \n\ "; static const char *Lightmap3blendFx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ texture texture3; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ dword color3; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ float4 factor3; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ \n\ // **** 4 stages technique \n\ pixelshader four_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ tex t3; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mad r0.xyz, c3, t3, r0; \n\ mul r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique four_stages_4 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShader = (four_stages_ps); \n\ } \n\ } \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_0_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_0_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ DestBlend = one; \n\ Lighting = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ ColorOp[2] = DISABLE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ AlphaOp[2] = DISABLE; \n\ PixelShader = NULL; \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ pass p2 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ } \n\ \n\ "; static const char *Lightmap3blend_x2Fx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ texture texture3; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ dword color3; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ float4 factor3; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ // modulate the dyn light by 0.5, because of MODULATE2X \n\ float4 g_dyn_factor = { 0.5f, 0.5f, 0.5f, 1.0f }; \n\ \n\ \n\ // **** 4 stages technique \n\ pixelshader four_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ tex t3; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mad r0.xyz, c3, t3, r0; \n\ mul_x2 r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique four_stages_4 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShader = (four_stages_ps); \n\ } \n\ } \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_0_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul_x2 r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_0_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ DestBlend = one; \n\ Lighting = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ ColorOp[2] = DISABLE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ AlphaOp[2] = DISABLE; \n\ PixelShader = NULL; \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ pass p2 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ } \n\ \n\ "; static const char *Lightmap3_x2Fx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ texture texture3; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ dword color3; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ float4 factor3; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ // modulate the dyn light by 0.5, because of MODULATE2X \n\ float4 g_dyn_factor = { 0.5f, 0.5f, 0.5f, 1.0f }; \n\ \n\ \n\ // **** 4 stages technique \n\ pixelshader four_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ tex t3; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mad r0.xyz, c3, t3, r0; \n\ mul_x2 r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique four_stages_4 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShader = (four_stages_ps); \n\ } \n\ } \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_0_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul_x2 r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_0_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ Lighting = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ ColorOp[2] = DISABLE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; // for case when there's alpha test \n\ AlphaOp[2] = DISABLE; \n\ PixelShader = NULL; \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; // alpha in case were alpha test is used\n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ pass p2 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ } \n\ \n\ \n\ \n\ "; static const char *Lightmap4Fx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ texture texture3; \n\ texture texture4; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ dword color3; \n\ dword color4; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ float4 factor3; \n\ float4 factor4; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ \n\ // **** 5 stages technique \n\ pixelshader five_stages_ps = asm \n\ { \n\ ps_1_4; \n\ texld r0, t0; \n\ texld r1, t1; \n\ texld r2, t2; \n\ texld r3, t3; \n\ texld r4, t4; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r1.xyz, c1, r1, v0; \n\ mad r1.xyz, c2, r2, r1; \n\ mad r1.xyz, c3, r3, r1; \n\ mad r1.xyz, c4, r4, r1; \n\ mul r0.xyz, r1, r0; \n\ }; \n\ \n\ technique five_stages_5 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ TexCoordIndex[4] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ Texture[4] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShaderConstant[4] = ; \n\ PixelShader = (five_stages_ps); \n\ } \n\ } \n\ \n\ // **** 4 stages technique \n\ pixelshader four_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ tex t3; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mad r0.xyz, c3, t3, r0; \n\ mul r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique four_stages_4 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShader = (four_stages_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ ColorOp[2] = DISABLE; \n\ ColorOp[3] = DISABLE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ AlphaOp[2] = DISABLE; \n\ AlphaOp[3] = DISABLE; \n\ PixelShader = NULL; \n\ } \n\ } \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_0_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ // 2 pass with the same pixel shader \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_0_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ // second pass: shut down all lighting (lmc ambient term and dynamic lighting already added in first pass)\n\ MaterialEmissive= ; \n\ MaterialDiffuse= ; \n\ \n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ pass p2 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ pass p3 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ } \n\ \n\ \n\ "; static const char *Lightmap4blendFx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ texture texture3; \n\ texture texture4; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ dword color3; \n\ dword color4; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ float4 factor3; \n\ float4 factor4; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ float4 g_dyn_factor = { 1.0f, 1.0f, 1.0f, 1.0f }; \n\ \n\ \n\ // **** 5 stages technique \n\ pixelshader five_stages_ps = asm \n\ { \n\ ps_1_4; \n\ texld r0, t0; \n\ texld r1, t1; \n\ texld r2, t2; \n\ texld r3, t3; \n\ texld r4, t4; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r1.xyz, c1, r1, v0; \n\ mad r1.xyz, c2, r2, r1; \n\ mad r1.xyz, c3, r3, r1; \n\ mad r1.xyz, c4, r4, r1; \n\ mul r0.xyz, r1, r0; \n\ mov r0.w, r0; \n\ }; \n\ \n\ technique five_stages_5 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ TexCoordIndex[4] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ Texture[4] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShaderConstant[4] = ; \n\ PixelShader = (five_stages_ps); \n\ } \n\ } \n\ \n\ // **** 4 stages technique \n\ pixelshader four_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ tex t3; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mad r0.xyz, c3, t3, r0; \n\ mul r0.xyz, r0, t0; \n\ mov r0.w, t0; \n\ }; \n\ \n\ technique four_stages_4 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShader = (four_stages_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ DestBlend = one; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ ColorOp[2] = DISABLE; \n\ ColorOp[3] = DISABLE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ AlphaOp[2] = DISABLE; \n\ AlphaOp[3] = DISABLE; \n\ PixelShader = NULL; \n\ } \n\ } \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_0_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul r0.xyz, r0, t0; \n\ mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ // 2 pass with the same pixel shader \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_0_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ // second pass: shut down all lighting (lmc ambient term and dynamic lighting already added in first pass)\n\ MaterialEmissive= ; \n\ MaterialDiffuse= ; \n\ \n\ DestBlend = one; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ pass p2 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ pass p3 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ } \n\ \n\ \n\ \n\ "; static const char *Lightmap4blend_x2Fx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ texture texture3; \n\ texture texture4; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ dword color3; \n\ dword color4; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ float4 factor3; \n\ float4 factor4; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ // modulate the dyn light by 0.5, because of MODULATE2X \n\ float4 g_dyn_factor = { 0.5f, 0.5f, 0.5f, 1.0f }; \n\ \n\ \n\ // **** 5 stages technique \n\ pixelshader five_stages_ps = asm \n\ { \n\ ps_1_4; \n\ texld r0, t0; \n\ texld r1, t1; \n\ texld r2, t2; \n\ texld r3, t3; \n\ texld r4, t4; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r1.xyz, c1, r1, v0; \n\ mad r1.xyz, c2, r2, r1; \n\ mad r1.xyz, c3, r3, r1; \n\ mad r1.xyz, c4, r4, r1; \n\ mul_x2 r0.xyz, r1, r0; \n\ }; \n\ \n\ technique five_stages_5 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ TexCoordIndex[4] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ Texture[4] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShaderConstant[4] = ; \n\ PixelShader = (five_stages_ps); \n\ } \n\ } \n\ \n\ // **** 4 stages technique \n\ pixelshader four_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ tex t3; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mad r0.xyz, c3, t3, r0; \n\ mul_x2 r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique four_stages_4 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShader = (four_stages_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ DestBlend = one; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ ColorOp[2] = DISABLE; \n\ ColorOp[3] = DISABLE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ AlphaOp[2] = DISABLE; \n\ AlphaOp[3] = DISABLE; \n\ PixelShader = NULL; \n\ } \n\ } \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_0_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul_x2 r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ // 2 pass with the same pixel shader \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_0_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ // second pass: shut down all lighting (lmc ambient term and dynamic lighting already added in first pass)\n\ MaterialEmissive= ; \n\ MaterialDiffuse= ; \n\ \n\ DestBlend = one; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = true; \n\ SrcBlend = srcalpha; \n\ DestBlend = invsrcalpha; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ pass p2 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ pass p3 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ } \n\ \n\ \n\ \n\ "; static const char *Lightmap4_x2Fx = " \n\ texture texture0; \n\ texture texture1; \n\ texture texture2; \n\ texture texture3; \n\ texture texture4; \n\ // Color0 is the Ambient Added to the lightmap (for Lightmap 8 bit compression)\n\ // Other colors are the lightmap Factors for each lightmap \n\ dword color0; \n\ dword color1; \n\ dword color2; \n\ dword color3; \n\ dword color4; \n\ float4 factor0; \n\ float4 factor1; \n\ float4 factor2; \n\ float4 factor3; \n\ float4 factor4; \n\ \n\ float4 g_black = { 0.0f, 0.0f, 0.0f, 1.0f }; \n\ // modulate the dyn light by 0.5, because of MODULATE2X \n\ float4 g_dyn_factor = { 0.5f, 0.5f, 0.5f, 1.0f }; \n\ \n\ \n\ // **** 5 stages technique \n\ pixelshader five_stages_ps = asm \n\ { \n\ ps_1_4; \n\ texld r0, t0; \n\ texld r1, t1; \n\ texld r2, t2; \n\ texld r3, t3; \n\ texld r4, t4; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r1.xyz, c1, r1, v0; \n\ mad r1.xyz, c2, r2, r1; \n\ mad r1.xyz, c3, r3, r1; \n\ mad r1.xyz, c4, r4, r1; \n\ mul_x2 r0.xyz, r1, r0; \n\ }; \n\ \n\ technique five_stages_5 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ TexCoordIndex[4] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ Texture[4] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShaderConstant[4] = ; \n\ PixelShader = (five_stages_ps); \n\ } \n\ } \n\ \n\ // **** 4 stages technique \n\ pixelshader four_stages_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ tex t3; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mad r0.xyz, c3, t3, r0; \n\ mul_x2 r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique four_stages_4 \n\ { \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ TexCoordIndex[3] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShaderConstant[3] = ; \n\ PixelShader = (four_stages_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ ColorOp[2] = DISABLE; \n\ ColorOp[3] = DISABLE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ AlphaOp[2] = DISABLE; \n\ AlphaOp[3] = DISABLE; \n\ PixelShader = NULL; \n\ } \n\ } \n\ \n\ // **** 3 stages technique \n\ pixelshader three_stages_0_ps = asm \n\ { \n\ ps_1_1; \n\ tex t0; \n\ tex t1; \n\ tex t2; \n\ // multiply lightmap with factor, and add with LMCAmbient+DynamicLight term\n\ mad r0.xyz, c1, t1, v0; \n\ mad r0.xyz, c2, t2, r0; \n\ mul_x2 r0.xyz, r0, t0; \n\ +mov r0.w, t0; \n\ }; \n\ \n\ technique three_stages_3 \n\ { \n\ // 2 pass with the same pixel shader \n\ pass p0 \n\ { \n\ TexCoordIndex[2] = 1; \n\ \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ PixelShader = (three_stages_0_ps); \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ // second pass: shut down all lighting (lmc ambient term and dynamic lighting already added in first pass)\n\ MaterialEmissive= ; \n\ MaterialDiffuse= ; \n\ \n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShaderConstant[2] = ; \n\ } \n\ } \n\ \n\ // **** 2 stages, no pixel shader technique \n\ technique two_stages_2 \n\ { \n\ pass p0 \n\ { \n\ // Use Emissive For LMCAmbient, and diffuse for per vertex dynamic lighting\n\ Lighting = true; \n\ MaterialEmissive= ; \n\ MaterialAmbient= ; \n\ MaterialDiffuse= ; \n\ MaterialSpecular= ; \n\ AlphaBlendEnable = false; \n\ \n\ // the DiffuseTexture texture 0 is in last stage \n\ TexCoordIndex[0] = 1; \n\ TexCoordIndex[1] = 0; \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MULTIPLYADD; \n\ ColorArg0[0] = DIFFUSE; \n\ ColorArg1[0] = TFACTOR; \n\ ColorArg2[0] = TEXTURE; \n\ ColorOp[1] = MODULATE2X; \n\ ColorArg1[1] = CURRENT; \n\ ColorArg2[1] = TEXTURE; \n\ // Alpha stage 0 unused \n\ AlphaOp[0] = SELECTARG1; \n\ AlphaArg1[0] = TFACTOR; \n\ AlphaOp[1] = SELECTARG1; \n\ AlphaArg1[1] = TEXTURE; \n\ } \n\ pass p1 \n\ { \n\ FogColor = 0x00000000; // don't accumulate fog several times\n\ Lighting = false; \n\ AlphaBlendEnable = true; \n\ SrcBlend = one; \n\ DestBlend = one; \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ ColorOp[0] = MODULATE; \n\ } \n\ pass p2 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ pass p3 \n\ { \n\ Texture[0] = ; \n\ TextureFactor = ; \n\ } \n\ } \n\ \n\ \n\ "; static const char *Water_diffuseFx = " \n\ texture texture0; // bumpmap0 \n\ texture texture1; // bumpmap1 \n\ texture texture2; // envmap \n\ texture texture3; // diffuse \n\ \n\ float4 factor0; // bumpmap0 scale \n\ float4 factor1; // bumpmap1 scale \n\ float scalarFloat0; // bump scale for 1_1 version \n\ \n\ pixelshader water_diffuse_2_0 = asm \n\ { \n\ ps_2_0; \n\ dcl t0.xy; \n\ dcl t1.xy; \n\ dcl t2.xy; \n\ dcl t3.xy; \n\ dcl_2d s0; \n\ dcl_2d s1; \n\ dcl_2d s2; \n\ dcl_2d s3; \n\ //read bump map 0 \n\ texld r0, t0, s0; \n\ //bias result (include scaling) \n\ mad r0.xy, r0, c0.z, c0; \n\ add r0.xy, r0, t1; \n\ //read bump map 1 \n\ texld r0, r0, s1; \n\ //bias result (include scaling) \n\ mad r0.xy, r0, c1.z, c1; \n\ //add envmap coord \n\ add r0.xy, r0, t2; \n\ // read envmap \n\ texld r0, r0, s2; \n\ // read diffuse \n\ texld r1, t3, s3; \n\ mul r0, r0, r1; \n\ mov oC0, r0 \n\ }; \n\ \n\ technique technique_water_diffuse_2_0 \n\ { \n\ pass p0 \n\ { \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ PixelShaderConstant[0] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShader = (water_diffuse_2_0); \n\ } \n\ }; \n\ \n\ pixelshader water_diffuse_1_4 = asm \n\ { \n\ ps_1_4; \n\ texld r0, t0; \n\ texld r1, t1; \n\ texcrd r2.xyz, t2; \n\ mad r2.xy, r0_bx2, c0, r2; \n\ mad r2.xy, r1_bx2, c1, r2; \n\ phase \n\ texld r2, r2; \n\ texld r3, t3; \n\ mul r0, r2, r3; \n\ }; \n\ \n\ technique technique_water_diffuse_1_4 \n\ { \n\ pass p0 \n\ { \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ PixelShaderConstant[0] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShader = (water_diffuse_1_4); \n\ } \n\ }; \n\ \n\ pixelshader water_diffuse_1_1 = asm \n\ { \n\ // note in OpenGL on nVidia cards, it is permitted to chain 2 texbem so the effect is less nice there (no bumpmap animation)\n\ ps_1_1; \n\ tex t1; \n\ texbem t2, t1; \n\ tex t3; \n\ mul r0, t3, t2; \n\ }; \n\ \n\ technique technique_water_diffuse_1_1 \n\ { \n\ pass p0 \n\ { \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ Texture[3] = ; \n\ PixelShaderConstant[0] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShader = (water_diffuse_1_1); \n\ BumpEnvMat00[2] = ; \n\ BumpEnvMat01[0] = 0; \n\ BumpEnvMat10[0] = 0; \n\ BumpEnvMat11[2] = ; \n\ } \n\ }; \n\ \n\ "; static const char *Water_no_diffuseFx = " \n\ texture texture0; // bumpmap0 \n\ texture texture1; // bumpmap1 \n\ texture texture2; // envmap \n\ \n\ float4 factor0; // bumpmap0 scale \n\ float4 factor1; // bumpmap1 scale \n\ float scalarFloat0; // bump scale for 1_1 version \n\ \n\ pixelshader water_no_diffuse_2_0 = asm \n\ { \n\ ps_2_0; \n\ dcl t0.xy; \n\ dcl t1.xy; \n\ dcl t2.xy; \n\ dcl_2d s0; \n\ dcl_2d s1; \n\ dcl_2d s2; \n\ //read bump map 0 \n\ texld r0, t0, s0; \n\ //bias result (include scaling) \n\ mad r0.xy, r0, c0.z, c0; \n\ add r0.xy, r0, t1; \n\ //read bump map 1 \n\ texld r0, r0, s1; \n\ //bias result (include scaling) \n\ mad r0.xy, r0, c1.z, c1; \n\ //add envmap coord \n\ add r0.xy, r0, t2; \n\ //read envmap \n\ texld r0, r0, s2; \n\ mov oC0, r0; \n\ }; \n\ \n\ technique technique_water_no_diffuse_2_0 \n\ { \n\ pass p0 \n\ { \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[0] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShader = (water_no_diffuse_2_0); \n\ } \n\ }; \n\ \n\ pixelshader water_no_diffuse_1_4 = asm \n\ { \n\ ps_1_4; \n\ texld r0, t0; \n\ texld r1, t1; \n\ texcrd r2.xyz, t2; \n\ mad r2.xy, r0_bx2, c0, r2; \n\ mad r2.xy, r1_bx2, c1, r2; \n\ phase \n\ texld r2, r2; \n\ mov r0, r2; \n\ }; \n\ \n\ technique technique_water_no_diffuse_1_4 \n\ { \n\ pass p0 \n\ { \n\ Texture[0] = ; \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[0] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShader = (water_no_diffuse_1_4); \n\ } \n\ }; \n\ \n\ pixelshader water_no_diffuse_1_1 = asm \n\ { \n\ // note in OpenGL on nVidia cards, it is permitted to chain 2 texbem so the effect is less nice there (no bumpmap animation)\n\ ps_1_1; \n\ tex t1; \n\ texbem t2, t1; \n\ mov r0, t2; \n\ }; \n\ \n\ technique technique_water_no_diffuse_1_1 \n\ { \n\ pass p0 \n\ { \n\ Texture[1] = ; \n\ Texture[2] = ; \n\ PixelShaderConstant[0] = ; \n\ PixelShaderConstant[1] = ; \n\ PixelShader = (water_no_diffuse_1_1); \n\ BumpEnvMat00[2] = ; \n\ BumpEnvMat01[0] = 0; \n\ BumpEnvMat10[0] = 0; \n\ BumpEnvMat11[2] = ; \n\ } \n\ }; \n\ \n\ "; void CDriverD3D::initInternalShaders() { H_AUTO_D3D(CDriverD3D_initInternalShaders) setFx(_ShaderLightmap0,"lightmap0Fx", Lightmap0Fx); setFx(_ShaderLightmap1,"lightmap1Fx", Lightmap1Fx); setFx(_ShaderLightmap2,"lightmap2Fx", Lightmap2Fx); setFx(_ShaderLightmap3,"lightmap3Fx", Lightmap3Fx); setFx(_ShaderLightmap4,"lightmap4Fx", Lightmap4Fx); setFx(_ShaderLightmap0Blend,"lightmap0blendFx", Lightmap0blendFx); setFx(_ShaderLightmap1Blend,"lightmap1blendFx", Lightmap1blendFx); setFx(_ShaderLightmap2Blend,"lightmap2blendFx", Lightmap2blendFx); setFx(_ShaderLightmap3Blend,"lightmap3blendFx", Lightmap3blendFx); setFx(_ShaderLightmap4Blend,"lightmap4blendFx", Lightmap4blendFx); setFx(_ShaderLightmap0X2,"lightmap0_x2Fx", Lightmap0_x2Fx); setFx(_ShaderLightmap1X2,"lightmap1_x2Fx", Lightmap1_x2Fx); setFx(_ShaderLightmap2X2,"lightmap2_x2Fx", Lightmap2_x2Fx); setFx(_ShaderLightmap3X2,"lightmap3_x2Fx", Lightmap3_x2Fx); setFx(_ShaderLightmap4X2,"lightmap4_x2Fx", Lightmap4_x2Fx); setFx(_ShaderLightmap0BlendX2,"lightmap0blend_x2Fx", Lightmap0blend_x2Fx); setFx(_ShaderLightmap1BlendX2,"lightmap1blend_x2Fx", Lightmap1blend_x2Fx); setFx(_ShaderLightmap2BlendX2,"lightmap2blend_x2Fx", Lightmap2blend_x2Fx); setFx(_ShaderLightmap3BlendX2,"lightmap3blend_x2Fx", Lightmap3blend_x2Fx); setFx(_ShaderLightmap4BlendX2,"lightmap4blend_x2Fx", Lightmap4blend_x2Fx); setFx(_ShaderCloud, "cloudFx", CloudFx); setFx(_ShaderWaterNoDiffuse,"water_no_diffuseFx", Water_no_diffuseFx); setFx(_ShaderWaterDiffuse, "water_diffuseFx", Water_diffuseFx); } // *************************************************************************** void CDriverD3D::releaseInternalShaders() { H_AUTO_D3D(CDriverD3D_releaseInternalShaders) _ShaderLightmap0._DrvInfo.kill(); _ShaderLightmap1._DrvInfo.kill(); _ShaderLightmap2._DrvInfo.kill(); _ShaderLightmap3._DrvInfo.kill(); _ShaderLightmap4._DrvInfo.kill(); _ShaderLightmap0Blend._DrvInfo.kill(); _ShaderLightmap1Blend._DrvInfo.kill(); _ShaderLightmap2Blend._DrvInfo.kill(); _ShaderLightmap3Blend._DrvInfo.kill(); _ShaderLightmap4Blend._DrvInfo.kill(); _ShaderLightmap0X2._DrvInfo.kill(); _ShaderLightmap1X2._DrvInfo.kill(); _ShaderLightmap2X2._DrvInfo.kill(); _ShaderLightmap3X2._DrvInfo.kill(); _ShaderLightmap4X2._DrvInfo.kill(); _ShaderLightmap0BlendX2._DrvInfo.kill(); _ShaderLightmap1BlendX2._DrvInfo.kill(); _ShaderLightmap2BlendX2._DrvInfo.kill(); _ShaderLightmap3BlendX2._DrvInfo.kill(); _ShaderLightmap4BlendX2._DrvInfo.kill(); _ShaderCloud._DrvInfo.kill(); _ShaderWaterNoDiffuse._DrvInfo.kill(); _ShaderWaterDiffuse._DrvInfo.kill(); } // *************************************************************************** bool CDriverD3D::setShaderTexture (uint textureHandle, ITexture *texture, CFXCache *cache) { H_AUTO_D3D(CDriverD3D_setShaderTexture ) // Setup the texture if (!setupTexture(*texture)) return false; // Set the main texture nlassert (_CurrentShader); CShaderDrvInfosD3D *shaderInfo = static_cast((IShaderDrvInfos*)_CurrentShader->_DrvInfo); nlassert (shaderInfo); ID3DXEffect *effect = shaderInfo->Effect; CTextureDrvInfosD3D *d3dtext = getTextureD3D (*texture); if (texture) { if (cache) { cache->Params.setTexture(textureHandle, d3dtext->Texture); } else { effect->SetTexture (shaderInfo->TextureHandle[textureHandle], d3dtext->Texture); } } // Add a ref on this texture _CurrentShaderTextures.push_back (CTextureRef()); CTextureRef &ref = _CurrentShaderTextures.back(); ref.NeLTexture = texture; ref.D3DTexture = d3dtext->Texture; return true; } // *************************************************************************** void CDriverD3D::disableHardwareTextureShader() { // cannot disable pixel shader under DX, because it crashes with lightmap // => no-op /* _DisableHardwarePixelShader = true; _PixelShader = false; */ } // *************************************************************************** void CDriverD3D::notifyAllShaderDrvOfLostDevice() { for(TShaderDrvInfoPtrList::iterator it = _ShaderDrvInfos.begin(); it != _ShaderDrvInfos.end(); ++it) { nlassert(*it); CShaderDrvInfosD3D *drvInfo = NLMISC::safe_cast(*it); if (drvInfo->Effect) { nlverify(drvInfo->Effect->OnLostDevice() == D3D_OK); } } } // *************************************************************************** void CDriverD3D::notifyAllShaderDrvOfResetDevice() { for(TShaderDrvInfoPtrList::iterator it = _ShaderDrvInfos.begin(); it != _ShaderDrvInfos.end(); ++it) { nlassert(*it); CShaderDrvInfosD3D *drvInfo = NLMISC::safe_cast(*it); if (drvInfo->Effect) { //nlverify( drvInfo->Effect->OnResetDevice(); //== D3D_OK); } } } // *************************************************************************** // state records (for .fx caching) // *************************************************************************** class CStateRecordLightEnable : public CStateRecord { public: DWORD Index; BOOL Enable; public: CStateRecordLightEnable(DWORD index, BOOL enable) : Index(index), Enable(enable) {} virtual void apply(class CDriverD3D &drv) { drv.enableLight ((uint8)Index, Enable!=FALSE); } }; // class CStateRecordLight : public CStateRecord { public: DWORD Index; D3DLIGHT9 Light; public: CStateRecordLight(DWORD index, const D3DLIGHT9 *pLight) : Index(index), Light(*pLight) {} virtual void apply(class CDriverD3D &drv) { drv._LightCache[Index].Light = Light; drv.touchRenderVariable (&drv._LightCache[Index]); } }; // class CStateRecordMaterial : public CStateRecord { public: D3DMATERIAL9 Material; public: CStateRecordMaterial(const D3DMATERIAL9 *pMaterial) : Material(*pMaterial) {} virtual void apply(class CDriverD3D &drv) { drv.setMaterialState(Material); } }; // class CStateRecordPixelShader : public CStateRecord { public: LPDIRECT3DPIXELSHADER9 PixelShader; public: CStateRecordPixelShader(LPDIRECT3DPIXELSHADER9 pixelShader) : PixelShader(pixelShader) {} virtual void apply(class CDriverD3D &drv) { drv.setPixelShader(PixelShader); } }; // class CStateRecordPixelShaderConstantB : public CStateRecord { public: std::vector Values; uint StartRegister; public: CStateRecordPixelShaderConstantB(DWORD startRegister, const BOOL *values, DWORD countVec4) : StartRegister(startRegister) { Values.resize(countVec4 * 4); std::copy(values, values + countVec4 * 4, Values.begin()); } virtual void apply(class CDriverD3D &drv) { const BOOL *curr = &Values[0]; const BOOL *last = &Values[0] + Values.size(); uint i = StartRegister; while (curr != last) { drv.setPixelShaderConstant (i, curr); curr += 4; ++ i; } } }; // class CStateRecordPixelShaderConstantF : public CStateRecord { public: std::vector Values; uint StartRegister; public: CStateRecordPixelShaderConstantF(DWORD startRegister, const FLOAT *values, DWORD countVec4) : StartRegister(startRegister) { Values.resize(countVec4 * 4); std::copy(values, values + countVec4 * 4, Values.begin()); } virtual void apply(class CDriverD3D &drv) { const FLOAT *curr = &Values[0]; const FLOAT *last = &Values[0] + Values.size(); uint i = StartRegister; while (curr != last) { drv.setPixelShaderConstant (i, curr); curr += 4; ++ i; } } }; // class CStateRecordPixelShaderConstantI : public CStateRecord { public: std::vector Values; uint StartRegister; public: CStateRecordPixelShaderConstantI(DWORD startRegister, const INT *values, DWORD countVec4) : StartRegister(startRegister) { Values.resize(countVec4 * 4); std::copy(values, values + countVec4 * 4, Values.begin()); } virtual void apply(class CDriverD3D &drv) { const INT *curr = &Values[0]; const INT *last = &Values[0] + Values.size(); uint i = StartRegister; while (curr != last) { drv.setPixelShaderConstant (i, curr); curr += 4; ++ i; } } }; // class CStateRecordRenderState : public CStateRecord { public: D3DRENDERSTATETYPE State; DWORD Value; public: CStateRecordRenderState(D3DRENDERSTATETYPE state, DWORD value) : State(state), Value(value) {} virtual void apply(class CDriverD3D &drv) { drv.setRenderState(State, Value); } }; // class CStateRecordSamplerState : public CStateRecord { public: DWORD Sampler; D3DSAMPLERSTATETYPE Type; DWORD Value; public: CStateRecordSamplerState(DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value) : Sampler(sampler), Type(type), Value(value) {} virtual void apply(class CDriverD3D &drv) { drv.setSamplerState(Sampler, Type, Value); } }; // class CStateRecordTexture : public CStateRecord { public: DWORD Stage; CRefPtr TexRef; LPDIRECT3DBASETEXTURE9 Texture; BOOL IsNelTexture; public: CStateRecordTexture(DWORD stage, LPDIRECT3DBASETEXTURE9 texture, ITexture *nelTexture) : Stage(stage), Texture(texture) { nlassert(Texture); H_AUTO_D3D(CDriverD3D_SetTexture ) // if not a NeL texture, should add a reference on texture, else use refptr instead IsNelTexture = nelTexture != NULL; TexRef = nelTexture; if (!IsNelTexture) { HRESULT r = Texture->AddRef(); nlassert(r == D3D_OK); } } ~CStateRecordTexture() { nlassert(Texture); // no default ctor, so texture should have been set if (!IsNelTexture) { nlassert(TexRef == NULL); HRESULT r = Texture->Release(); nlassert(r == D3D_OK); } } virtual void apply(class CDriverD3D &drv) { nlassert(Texture); if (TexRef) { drv.setTexture(Stage, TexRef); } else { drv.setTexture(Stage, Texture); } } }; // class CStateRecordTextureStageState : public CStateRecord { public: DWORD Stage; D3DTEXTURESTAGESTATETYPE Type; DWORD Value; public: CStateRecordTextureStageState(DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value) : Stage(stage), Type(type), Value(value) {} virtual void apply(class CDriverD3D &drv) { if (Type == D3DTSS_TEXCOORDINDEX) drv.setTextureIndexUV (Stage, Value); else drv.setTextureState (Stage, Type, Value); } }; // class CStateRecordTransform : public CStateRecord { public: D3DTRANSFORMSTATETYPE State; D3DMATRIX Matrix; public: CStateRecordTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX *pMatrix) : State(state), Matrix(*pMatrix) {} virtual void apply(class CDriverD3D &drv) { drv.setMatrix(State, Matrix); } }; // class CStateRecordVertexShader : public CStateRecord { public: LPDIRECT3DVERTEXSHADER9 Shader; public: CStateRecordVertexShader(LPDIRECT3DVERTEXSHADER9 shader) : Shader(shader) {} virtual void apply(class CDriverD3D &/* drv */) { nlassert(0); // not supported //drv.setVertexProgram(Shader); } }; // class CStateRecordVertexShaderConstantB : public CStateRecord { public: std::vector Values; uint StartRegister; public: CStateRecordVertexShaderConstantB(DWORD startRegister, const BOOL *values, DWORD countVec4) : StartRegister(startRegister) { Values.resize(countVec4 * 4); std::copy(values, values + countVec4 * 4, Values.begin()); } virtual void apply(class CDriverD3D &drv) { const BOOL *curr = &Values[0]; const BOOL *last = &Values[0] + Values.size(); uint i = StartRegister; while (curr != last) { drv.setVertexProgramConstant(i, curr); curr += 4; ++ i; } } }; class CStateRecordVertexShaderConstantF : public CStateRecord { public: std::vector Values; uint StartRegister; public: CStateRecordVertexShaderConstantF(DWORD startRegister, const FLOAT *values, DWORD countVec4) : StartRegister(startRegister) { Values.resize(countVec4 * 4); std::copy(values, values + countVec4 * 4, Values.begin()); } virtual void apply(class CDriverD3D &drv) { const FLOAT *curr = &Values[0]; const FLOAT *last = &Values[0] + Values.size(); uint i = StartRegister; while (curr != last) { drv.setVertexProgramConstant(i, curr); curr += 4; ++ i; } } }; class CStateRecordVertexShaderConstantI : public CStateRecord { public: std::vector Values; uint StartRegister; public: CStateRecordVertexShaderConstantI(DWORD startRegister, const INT *values, DWORD countVec4) : StartRegister(startRegister) { Values.resize(countVec4 * 4); std::copy(values, values + countVec4 * 4, Values.begin()); } virtual void apply(class CDriverD3D &drv) { const INT *curr = &Values[0]; const INT *last = &Values[0] + Values.size(); uint i = StartRegister; while (curr != last) { drv.setVertexProgramConstant(i, curr); curr += 4; ++ i; } } }; // state recorder HRESULT STDMETHODCALLTYPE CFXPassRecorder::QueryInterface(REFIID riid, LPVOID *ppvObj) { nlassert(Driver); return Driver->QueryInterface(riid, ppvObj); } ULONG STDMETHODCALLTYPE CFXPassRecorder::AddRef(VOID) { nlassert(Driver); return Driver->AddRef(); } ULONG STDMETHODCALLTYPE CFXPassRecorder::Release(VOID) { nlassert(Driver); return Driver->Release(); } HRESULT STDMETHODCALLTYPE CFXPassRecorder::LightEnable(DWORD Index, BOOL Enable) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordLightEnable(Index, Enable)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetFVF(DWORD /* FVF */) { nlassert(0); // not managed return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetLight(DWORD Index, CONST D3DLIGHT9* pLight) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordLight(Index, pLight)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetMaterial(CONST D3DMATERIAL9* pMaterial) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordMaterial(pMaterial)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetNPatchMode(FLOAT /* nSegments */) { nlassert(0); // not managed return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetPixelShader(LPDIRECT3DPIXELSHADER9 pShader) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordPixelShader(pShader)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetPixelShaderConstantB(UINT StartRegister, CONST BOOL* pConstantData, UINT RegisterCount) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordPixelShaderConstantB(StartRegister, pConstantData, RegisterCount)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetPixelShaderConstantF(UINT StartRegister, CONST FLOAT* pConstantData, UINT RegisterCount) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordPixelShaderConstantF(StartRegister, pConstantData, RegisterCount)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetPixelShaderConstantI(UINT StartRegister, CONST INT* pConstantData, UINT RegisterCount) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordPixelShaderConstantI(StartRegister, pConstantData, RegisterCount)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetRenderState(D3DRENDERSTATETYPE State, DWORD Value) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordRenderState(State, Value)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordSamplerState(Sampler, Type, Value)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture) { nlassert(Driver); nlassert(Target); // Look for the current texture uint i; const uint count = (uint)Driver->getCurrentShaderTextures().size(); for (i=0; igetCurrentShaderTextures()[i]; if (ref.D3DTexture == pTexture) { // Set the additionnal stage set by NeL texture (D3DSAMP_ADDRESSU, D3DSAMP_ADDRESSV, D3DSAMP_MAGFILTER, D3DSAMP_MINFILTER and D3DSAMP_MIPFILTER) Target->States.push_back(new CStateRecordTexture(Stage, pTexture, ref.NeLTexture)); break; } } if (i == count) { // The texture isn't a NeL texture (was created inside driver) Target->States.push_back(new CStateRecordTexture(Stage, pTexture, NULL)); } return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordTextureStageState(Stage, Type, Value)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordTransform(State, pMatrix)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetVertexShader(LPDIRECT3DVERTEXSHADER9 pShader) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordVertexShader(pShader)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetVertexShaderConstantB(UINT StartRegister, CONST BOOL* pConstantData, UINT RegisterCount) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordVertexShaderConstantB(StartRegister, pConstantData, RegisterCount)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetVertexShaderConstantF(UINT StartRegister, CONST FLOAT* pConstantData, UINT RegisterCount) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordVertexShaderConstantF(StartRegister, pConstantData, RegisterCount)); return D3D_OK; } HRESULT STDMETHODCALLTYPE CFXPassRecorder::SetVertexShaderConstantI(UINT StartRegister, CONST INT* pConstantData, UINT RegisterCount) { nlassert(Driver); nlassert(Target); Target->States.push_back(new CStateRecordVertexShaderConstantI(StartRegister, pConstantData, RegisterCount)); return D3D_OK; } //=================================================================================== CFXPassRecord::~CFXPassRecord() { for(std::vector::iterator it = States.begin(); it != States.end(); ++it) { delete *it; } } void CFXPassRecord::apply(CDriverD3D &drv) { for(std::vector::iterator it = States.begin(); it != States.end(); ++it) { (*it)->apply(drv); } } const uint NL_D3D_NUM_RENDER_FOR_FX_CACHING = 4; //=================================================================================== void CFXCache::setConstants(CShaderDrvInfosD3D *si) { nlassert(si); nlassert(si->Effect); for(uint k = 0; k < CFXInputParams::MaxNumParams; ++k) { if (Params.Textures[k].Set) si->Effect->SetTexture(si->TextureHandle[k], Params.Textures[k].Value); if (Params.Vectors[k].Set) si->Effect->SetFloatArray(si->FactorHandle[k], (CONST FLOAT *) &(Params.Vectors[k].Value), 4); if (Params.Colors[k].Set) si->Effect->SetInt(si->ColorHandle[k], Params.Colors[k].Value); if (Params.Floats[k].Set) si->Effect->SetFloat(si->ScalarFloatHandle[k], Params.Floats[k].Value); } } void CFXCache::begin(CShaderDrvInfosD3D *si, CDriverD3D *driver) { nlassert(driver); // amortize cost of caching for animated material -> ensure that the parameters don't change for // a few number of display before doing caching if (Params.Touched) { Steadyness = 0; Passes.clear(); NumPasses = 0; Params.Touched = false; return; } if (!Params.Touched) { ++ Steadyness; } if (Steadyness < NL_D3D_NUM_RENDER_FOR_FX_CACHING) { NumPasses = 0; Passes.clear(); return; } if (Passes.empty()) // must record shader ? { Passes.clear(); UINT numPasses; CFXPassRecorder pr; pr.Driver = driver; si->Effect->SetStateManager(&pr); // Set constants setConstants(si); // HRESULT r = si->Effect->Begin(&numPasses, D3DXFX_DONOTSAVESTATE|D3DXFX_DONOTSAVESHADERSTATE); nlassert(r == D3D_OK); Passes.resize(numPasses); for(uint k = 0; k < numPasses; ++k) { pr.Target = &Passes[k]; #if (DIRECT3D_VERSION >= 0x0900) && (D3D_SDK_VERSION >= 32) si->Effect->BeginPass(k); si->Effect->EndPass(); #else si->Effect->Pass(k); #endif } r = si->Effect->End(); nlassert(r == D3D_OK); NumPasses = numPasses; si->Effect->SetStateManager(driver); } } void CFXCache::applyPass(class CDriverD3D &drv, CShaderDrvInfosD3D *si, uint passIndex) { if (Passes.empty() && NumPasses == 0) { // the shader has not been cached yet (maybe animated) // so uses the standard path UINT numPasses; setConstants(si); HRESULT r = si->Effect->Begin(&numPasses, D3DXFX_DONOTSAVESTATE|D3DXFX_DONOTSAVESHADERSTATE); nlassert(r == D3D_OK); NumPasses = numPasses; } nlassert(passIndex < NumPasses); if (Passes.empty()) { #if (DIRECT3D_VERSION >= 0x0900) && (D3D_SDK_VERSION >= 32) HRESULT r = si->Effect->BeginPass(passIndex); si->Effect->EndPass (); #else HRESULT r = si->Effect->Pass(passIndex); #endif nlassert(r == D3D_OK); } else { Passes[passIndex].apply(drv); } } void CFXCache::end(CShaderDrvInfosD3D *si) { if (Passes.empty()) { HRESULT r = si->Effect->End(); nlassert(r == D3D_OK); } } void CFXCache::reset() { Params.reset(); Passes.clear(); Steadyness = 0; } } // NL3D