You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1240 lines
38 KiB
C++
1240 lines
38 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
#include "RenderDll_precompiled.h"
|
|
#include "I3DEngine.h"
|
|
#include "CryHeaders.h"
|
|
#include "StringUtils.h" // stristr()
|
|
#include "../Common/Textures/TextureHelpers.h"
|
|
#include "../Common/Textures/TextureManager.h"
|
|
|
|
#if defined(WIN32) || defined(WIN64)
|
|
#include <direct.h>
|
|
#include <io.h>
|
|
#elif defined(LINUX)
|
|
|
|
#endif
|
|
|
|
//===============================================================================
|
|
#if !defined(_RELEASE)
|
|
// Texture names to be used for error / process loading indications
|
|
static const char* szReplaceMe = "EngineAssets/TextureMsg/ReplaceMe.tif";
|
|
#else
|
|
// Some of the textures here will direct to the regular DefaultSolids_diff to prevent eye catching
|
|
// bug textures in release mode
|
|
static const char* szReplaceMe = "EngineAssets/TextureMsg/ReplaceMeRelease.tif";
|
|
#endif
|
|
|
|
//===============================================================================
|
|
CShaderResources* CShaderMan::mfCreateShaderResources(const SInputShaderResources* Res, bool bShare)
|
|
{
|
|
uint16 i, j;
|
|
SInputShaderResources localCopySR = *Res; // pay attention to this local copy
|
|
|
|
// prepare local resources for cache-check, textures are looked up but not triggered for load
|
|
for ( auto& iter : localCopySR.m_TexturesResourcesMap )
|
|
{
|
|
SEfResTexture* pTextureRes = &(iter.second);
|
|
|
|
// Store off the previous texture's flags before we clean up the sampler slot
|
|
uint32 textureFlags = (pTextureRes->m_Sampler.m_pTex) ? pTextureRes->m_Sampler.m_pTex->GetFlags() : 0;
|
|
|
|
pTextureRes->m_Sampler.Cleanup();
|
|
if (!pTextureRes->m_Name.empty())
|
|
{ // If the texture that used to exist in this resource slot was created as an alpha texture
|
|
// e.g. - a gloss map stored in the alpha channel of a normal map (see CShaderMan::mfRefreshResources for some
|
|
// extra details on the texture slots that use the FT_ALPHA texture path), we need to pass the FT_ALPHA flag
|
|
// into mfFindResourceTexture so it can find the actual texture resource.
|
|
const uint32 alphaTextureFlags = textureFlags & FT_ALPHA;
|
|
|
|
// Find the actual texture resource according to the given name
|
|
pTextureRes->m_Sampler.m_pTex = mfFindResourceTexture(
|
|
pTextureRes->m_Name.c_str(), localCopySR.m_TexturePath.c_str(),
|
|
pTextureRes->m_Sampler.GetTexFlags() | alphaTextureFlags, pTextureRes);
|
|
|
|
if (pTextureRes->m_Sampler.m_pTex)
|
|
{ // increase usage counter if texture was found
|
|
pTextureRes->m_Sampler.m_pTex->AddRef();
|
|
}
|
|
}
|
|
/* [Shader System TO DO] - verify if possible to remove slot
|
|
else
|
|
{
|
|
AZ_Warning( "ShadersSystem", false, "CShaderMan::mfCreateShaderResources - texture name does not exist at slot %d - removing slot", iter->first);
|
|
pLocalCopySR.m_TexturesResourcesMap.erase(iter);
|
|
}
|
|
*/
|
|
}
|
|
|
|
// check local resources vs' global cache
|
|
int nFree = -1;
|
|
for (i = 1; i < CShader::s_ShaderResources_known.Num(); i++) // first entry is a null entry
|
|
{
|
|
// NOT thread safe can be modified from render thread in SRenderShaderResources dtor ()
|
|
// (if flushing of unloaded textures (UnloadLevel) is not complete before pre-loading of new materials)
|
|
CShaderResources* pLoadedSRes = CShader::s_ShaderResources_known[i];
|
|
if (!pLoadedSRes)
|
|
{
|
|
nFree = i; // find the first free slot in the bank
|
|
if (!bShare || Res->m_ShaderParams.size())
|
|
{
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
if (!bShare || Res->m_ShaderParams.size())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// [Shader System TO DO] - see if can be replaced with unified compare function
|
|
if (localCopySR.m_ResFlags == pLoadedSRes->GetResFlags() &&
|
|
localCopySR.m_LMaterial.m_Opacity == pLoadedSRes->GetStrengthValue(EFTT_OPACITY) &&
|
|
localCopySR.m_LMaterial.m_Emittance.a == pLoadedSRes->GetStrengthValue(EFTT_EMITTANCE) &&
|
|
localCopySR.m_AlphaRef == pLoadedSRes->GetAlphaRef() &&
|
|
localCopySR.m_TexturePath == pLoadedSRes->m_TexturePath)
|
|
{
|
|
// if there is not shader deformation or both deformations are identical
|
|
if ((!pLoadedSRes->m_pDeformInfo && !localCopySR.m_DeformInfo.m_eType) || (pLoadedSRes->m_pDeformInfo && *pLoadedSRes->m_pDeformInfo == localCopySR.m_DeformInfo))
|
|
{
|
|
// [Shader System TO DO] - optimize
|
|
// The following code runs over all slots and verify a match between current shader and
|
|
// loaded shaders If no match - break and add to the loaded.
|
|
for (j = 0; j < EFTT_MAX; j++)
|
|
{
|
|
SEfResTexture* pLoadedTexRes = pLoadedSRes->GetTextureResource(j);
|
|
SEfResTexture* pShaderTexRes = localCopySR.GetTextureResource(j);
|
|
|
|
// No loaded (cached) texture slot or no texture name for this slot
|
|
if (!pLoadedTexRes || pLoadedTexRes->m_Name.empty())
|
|
{
|
|
if (!pShaderTexRes || pShaderTexRes->m_Name.empty())
|
|
{ // match - no texture slot or texture name - move to the next slot
|
|
continue;
|
|
}
|
|
|
|
// slot exists but cannot be found in the resource - no shaders match - try the next cached shader
|
|
break;
|
|
}
|
|
// Cached slot entry with texture name exists - test to see if exists for the current shader
|
|
else if (!pShaderTexRes || pShaderTexRes->m_Name.empty())
|
|
{
|
|
break; // texture slot doesn't exist / no texture name for current shader - no match - move to next cached shader
|
|
}
|
|
|
|
// both slots exist - run a full comparison between the two shaders (current and cached)
|
|
if (*pLoadedTexRes != *pShaderTexRes)
|
|
{
|
|
break; // no match - move to the next cached shader
|
|
}
|
|
}
|
|
|
|
// The two shader resources fully match - return the cached shader resource (no need to load)
|
|
if (j == EFTT_MAX)
|
|
{
|
|
pLoadedSRes->AddRef(); // add usage count to this loaded shader resource
|
|
return pLoadedSRes;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// The current shader resource does not exist - create a dynamic copy to be loaded and
|
|
// insert to the cached resources bank.
|
|
CShaderResources* pSR = new CShaderResources(&localCopySR);
|
|
pSR->m_nRefCounter = 1;
|
|
if (!CShader::s_ShaderResources_known.Num())
|
|
{
|
|
CShader::s_ShaderResources_known.AddIndex(1);
|
|
CShaderResources* pSRNULL = new CShaderResources;
|
|
pSRNULL->m_nRefCounter = 1;
|
|
CShader::s_ShaderResources_known[0] = pSRNULL;
|
|
}
|
|
else if (nFree < 0 && CShader::s_ShaderResources_known.Num() >= MAX_REND_SHADER_RES)
|
|
{
|
|
Warning("ERROR: CShaderMan::mfCreateShaderResources: MAX_REND_SHADER_RESOURCES hit");
|
|
pSR->Release();
|
|
return CShader::s_ShaderResources_known[1];
|
|
}
|
|
if (nFree > 0)
|
|
{
|
|
pSR->m_Id = nFree;
|
|
pSR->m_IdGroup = pSR->m_Id;
|
|
CShader::s_ShaderResources_known[nFree] = pSR;
|
|
}
|
|
else
|
|
{
|
|
pSR->m_Id = CShader::s_ShaderResources_known.Num();
|
|
pSR->m_IdGroup = pSR->m_Id;
|
|
CShader::s_ShaderResources_known.AddElem(pSR);
|
|
}
|
|
|
|
return pSR;
|
|
}
|
|
|
|
void CShaderResources::SetShaderParams(SInputShaderResources* pDst, IShader* pSH)
|
|
{
|
|
ReleaseParams();
|
|
m_ShaderParams = pDst->m_ShaderParams;
|
|
|
|
UpdateConstants(pSH);
|
|
}
|
|
|
|
|
|
uint32 SShaderItem::PostLoad()
|
|
{
|
|
uint32 nPreprocessFlags = 0;
|
|
CShader* pSH = (CShader*)m_pShader;
|
|
CShaderResources* pR = (CShaderResources*)m_pShaderResources;
|
|
|
|
if (pSH->m_Flags2 & EF2_PREPR_GENCLOUDS)
|
|
{
|
|
nPreprocessFlags |= FSPR_GENCLOUDS;
|
|
}
|
|
if (pSH->m_Flags2 & EF2_PREPR_SCANWATER)
|
|
{
|
|
nPreprocessFlags |= FSPR_SCANTEXWATER | FB_PREPROCESS;
|
|
}
|
|
|
|
nPreprocessFlags |= FB_GENERAL;
|
|
const SShaderTechnique* pTech = GetTechnique();
|
|
if (pR)
|
|
{
|
|
pR->PostLoad(pSH);
|
|
|
|
for (auto& iter : pR->m_TexturesResourcesMap )
|
|
{
|
|
SEfResTexture* pTexture = &(iter.second);
|
|
bool is2DTexture = (pTexture->m_Sampler.m_eTexType == eTT_Auto2D || pTexture->m_Sampler.m_eTexType == eTT_Dyn2D);
|
|
|
|
if (!pTexture->m_Sampler.m_pTarget)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (is2DTexture)
|
|
{
|
|
if (gRenDev->m_RP.m_eQuality == eRQ_Low)
|
|
{
|
|
pTexture->m_Sampler.m_eTexType = eTT_2D;
|
|
}
|
|
pR->m_ResFlags |= MTL_FLAG_NOTINSTANCED;
|
|
nPreprocessFlags |= FSPR_SCANTEX;
|
|
}
|
|
pR->m_RTargets.AddElem(pTexture->m_Sampler.m_pTarget);
|
|
}
|
|
}
|
|
|
|
if (pTech && pTech->m_Passes.Num() && (pTech->m_Passes[0].m_RenderState & GS_ALPHATEST_MASK))
|
|
{
|
|
if (pR && !pR->m_AlphaRef)
|
|
{
|
|
pR->m_AlphaRef = 0.5f;
|
|
}
|
|
}
|
|
|
|
// Update persistent batch flags
|
|
if (pTech)
|
|
{
|
|
if (pTech->m_nTechnique[TTYPE_Z] > 0)
|
|
{
|
|
nPreprocessFlags |= FB_Z;
|
|
|
|
// ZPrepass only for non-alpha tested/blended geometry (decals, terrain).
|
|
// We assume vegetation is special case due to potential massive overdraw
|
|
if (pTech->m_nTechnique[TTYPE_ZPREPASS] > 0)
|
|
{
|
|
const bool bAlphaTested = (pR && pR->IsAlphaTested());
|
|
if (!bAlphaTested)
|
|
{
|
|
nPreprocessFlags |= FB_ZPREPASS;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!(pTech->m_Flags & FHF_POSITION_INVARIANT) && ((pTech->m_Flags & FHF_TRANSPARENT) || (pR && pR->IsTransparent())))
|
|
{
|
|
nPreprocessFlags |= FB_TRANSPARENT;
|
|
}
|
|
|
|
if (pTech->m_nTechnique[TTYPE_WATERREFLPASS] > 0)
|
|
{
|
|
nPreprocessFlags |= FB_WATER_REFL;
|
|
}
|
|
|
|
if (pTech->m_nTechnique[TTYPE_WATERCAUSTICPASS] > 0)
|
|
{
|
|
nPreprocessFlags |= FB_WATER_CAUSTIC;
|
|
}
|
|
|
|
if ((pSH->m_Flags2 & EF2_SKINPASS))
|
|
{
|
|
nPreprocessFlags |= FB_SKIN;
|
|
}
|
|
|
|
if (CRenderer::CV_r_SoftAlphaTest && pTech->m_nTechnique[TTYPE_SOFTALPHATESTPASS] > 0)
|
|
{
|
|
nPreprocessFlags |= FB_SOFTALPHATEST;
|
|
}
|
|
|
|
if (pSH->m_Flags2 & EF2_EYE_OVERLAY)
|
|
{
|
|
nPreprocessFlags |= FB_EYE_OVERLAY;
|
|
}
|
|
|
|
if (pSH->m_Flags & EF_REFRACTIVE)
|
|
{
|
|
if (CRenderer::CV_r_Refraction)
|
|
{
|
|
nPreprocessFlags |= FB_TRANSPARENT;
|
|
}
|
|
else
|
|
{
|
|
AZ_Warning("ShadersSystem", false,
|
|
"Shader %s use refraction but it's not enabled for this configuration. Check the value of the CVAR r_Refraction.",
|
|
pSH->m_NameShader.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pTech)
|
|
{
|
|
nPreprocessFlags |= pTech->m_nPreprocessFlags;
|
|
}
|
|
|
|
if (nPreprocessFlags & FSPR_MASK)
|
|
{
|
|
nPreprocessFlags |= FB_PREPROCESS;
|
|
}
|
|
|
|
return nPreprocessFlags;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// [Shader System TO DO] - remove and replace with data driven from the shader files
|
|
// This method should be per shader type and not generic to the entire engine.
|
|
|
|
// This method associates fixed slots with known contextual material textures
|
|
// The engine slots are left unhandled and will be assigned through the
|
|
// shader and engine side - explore how!
|
|
//------------------------------------------------------------------------------
|
|
EEfResTextures CShaderMan::mfCheckTextureSlotName(const char* mapname)
|
|
{
|
|
EEfResTextures slot = EFTT_UNKNOWN;
|
|
|
|
if (!azstricmp(mapname, "$Diffuse"))
|
|
{
|
|
slot = EFTT_DIFFUSE;
|
|
}
|
|
else if (!azstricmp(mapname, "$Normal"))
|
|
{
|
|
slot = EFTT_NORMALS;
|
|
}
|
|
else if (!azstricmp(mapname, "$Specular"))
|
|
{
|
|
slot = EFTT_SPECULAR;
|
|
}
|
|
else if (!azstricmp(mapname, "$Env"))
|
|
{
|
|
slot = EFTT_ENV;
|
|
}
|
|
else if (!azstricmp(mapname, "$Detail"))
|
|
{
|
|
slot = EFTT_DETAIL_OVERLAY;
|
|
}
|
|
else if (!azstricmp(mapname, "$SecondSmoothness"))
|
|
{
|
|
slot = EFTT_SECOND_SMOOTHNESS;
|
|
}
|
|
else if (!azstricmp(mapname, "$Height"))
|
|
{
|
|
slot = EFTT_HEIGHT;
|
|
}
|
|
else if (!azstricmp(mapname, "$DecalOverlay"))
|
|
{
|
|
slot = EFTT_DECAL_OVERLAY;
|
|
}
|
|
else if (!azstricmp(mapname, "$Subsurface"))
|
|
{
|
|
slot = EFTT_SUBSURFACE;
|
|
}
|
|
else if (!azstricmp(mapname, "$CustomMap"))
|
|
{ // Used as Diffuse 2 when BlendLayer is enabled
|
|
slot = EFTT_CUSTOM;
|
|
}
|
|
else if (!azstricmp(mapname, "$Specular2"))
|
|
{ // Used as Specular 2 when BlendLayer is enabled
|
|
slot = EFTT_SPECULAR_2;
|
|
}
|
|
else if (!azstricmp(mapname, "$CustomSecondaryMap"))
|
|
{ // Used as Normal 2 when BlendLayer is enabled
|
|
slot = EFTT_CUSTOM_SECONDARY;
|
|
}
|
|
else if (!azstricmp(mapname, "$Opacity"))
|
|
{ // Used as Blend Map for BlendLayer is enabled
|
|
slot = EFTT_OPACITY;
|
|
}
|
|
else if (!azstricmp(mapname, "$Smoothness"))
|
|
{
|
|
slot = EFTT_SMOOTHNESS;
|
|
}
|
|
else if (!azstricmp(mapname, "$Emittance"))
|
|
{
|
|
slot = EFTT_EMITTANCE;
|
|
}
|
|
else if (!azstricmp(mapname, "$Occlusion"))
|
|
{
|
|
slot = EFTT_OCCLUSION;
|
|
}
|
|
// backwards compatible names
|
|
else if (!azstricmp(mapname, "$Cubemap"))
|
|
{
|
|
slot = EFTT_ENV;
|
|
}
|
|
else if (!azstricmp(mapname, "$Translucency"))
|
|
{
|
|
slot = EFTT_SECOND_SMOOTHNESS;
|
|
}
|
|
else if (!azstricmp(mapname, "$BumpDiffuse"))
|
|
{
|
|
slot = EFTT_SECOND_SMOOTHNESS; //EFTT_BUMP_DIFFUSE;
|
|
}
|
|
else if (!azstricmp(mapname, "$BumpHeight"))
|
|
{
|
|
slot = EFTT_HEIGHT; //EFTT_BUMP_HEIGHT;
|
|
}
|
|
else if (!azstricmp(mapname, "$Bump"))
|
|
{
|
|
slot = EFTT_NORMALS; //EFTT_BUMP;
|
|
}
|
|
else if (!azstricmp(mapname, "$Gloss"))
|
|
{
|
|
slot = EFTT_SPECULAR; //EFTT_GLOSS;
|
|
}
|
|
else if (!azstricmp(mapname, "$GlossNormalA"))
|
|
{
|
|
slot = EFTT_SMOOTHNESS; //EFTT_GLOSS_NORMAL_A;
|
|
}
|
|
|
|
return slot;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// [Shader System TO DO] - data driven per update frequencies and the slots map
|
|
//------------------------------------------------------------------------------
|
|
CTexture* CShaderMan::mfCheckTemplateTexName(const char* mapname, [[maybe_unused]] ETEX_Type eTT)
|
|
{
|
|
CTexture* TexPic = NULL;
|
|
if (mapname[0] != '$')
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
{
|
|
EEfResTextures slot = mfCheckTextureSlotName(mapname);
|
|
|
|
if (slot != EFTT_MAX)
|
|
{
|
|
return &(*CTexture::s_ShaderTemplates)[slot];
|
|
}
|
|
}
|
|
|
|
if (!azstricmp(mapname, "$ShadowPoolAtlas"))
|
|
{
|
|
TexPic = CTexture::s_ptexRT_ShadowPool;
|
|
}
|
|
else
|
|
if (!azstrnicmp(mapname, "$ShadowID", 9))
|
|
{
|
|
int n = atoi(&mapname[9]);
|
|
TexPic = CTexture::s_ptexShadowID[n];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$FromRE") || !azstricmp(mapname, "$FromRE0"))
|
|
{
|
|
TexPic = CTexture::s_ptexFromRE[0];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$FromRE1"))
|
|
{
|
|
TexPic = CTexture::s_ptexFromRE[1];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$FromRE2"))
|
|
{
|
|
TexPic = CTexture::s_ptexFromRE[2];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$FromRE3"))
|
|
{
|
|
TexPic = CTexture::s_ptexFromRE[3];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$FromRE4"))
|
|
{
|
|
TexPic = CTexture::s_ptexFromRE[4];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$FromRE5"))
|
|
{
|
|
TexPic = CTexture::s_ptexFromRE[5];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$FromRE6"))
|
|
{
|
|
TexPic = CTexture::s_ptexFromRE[6];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$FromRE7"))
|
|
{
|
|
TexPic = CTexture::s_ptexFromRE[7];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$VolObj_Density"))
|
|
{
|
|
TexPic = CTexture::s_ptexVolObj_Density;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$VolObj_Shadow"))
|
|
{
|
|
TexPic = CTexture::s_ptexVolObj_Shadow;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$ColorChart"))
|
|
{
|
|
TexPic = CTexture::s_ptexColorChart;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$FromObj"))
|
|
{
|
|
TexPic = CTexture::s_ptexFromObj;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SvoTree"))
|
|
{
|
|
TexPic = CTexture::s_ptexSvoTree;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SvoTris"))
|
|
{
|
|
TexPic = CTexture::s_ptexSvoTris;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SvoGlobalCM"))
|
|
{
|
|
TexPic = CTexture::s_ptexSvoGlobalCM;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SvoRgbs"))
|
|
{
|
|
TexPic = CTexture::s_ptexSvoRgbs;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SvoNorm"))
|
|
{
|
|
TexPic = CTexture::s_ptexSvoNorm;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SvoOpac"))
|
|
{
|
|
TexPic = CTexture::s_ptexSvoOpac;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$FromObjCM"))
|
|
{
|
|
TexPic = CTexture::s_ptexFromObjCM;
|
|
}
|
|
else
|
|
if (!azstrnicmp(mapname, "$White", 6))
|
|
{
|
|
TexPic = CTextureManager::Instance()->GetWhiteTexture();
|
|
}
|
|
else
|
|
if (!azstrnicmp(mapname, "$RT_2D", 6))
|
|
{
|
|
TexPic = CTexture::s_ptexRT_2D;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$PrevFrameScaled"))
|
|
{
|
|
TexPic = CTexture::s_ptexPrevFrameScaled;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$BackBuffer"))
|
|
{
|
|
TexPic = CTexture::s_ptexBackBuffer;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$ModelHUD"))
|
|
{
|
|
TexPic = CTexture::s_ptexModelHudBuffer;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$BackBufferScaled_d2"))
|
|
{
|
|
TexPic = CTexture::s_ptexBackBufferScaled[0];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$BackBufferScaled_d4"))
|
|
{
|
|
TexPic = CTexture::s_ptexBackBufferScaled[1];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$BackBufferScaled_d8"))
|
|
{
|
|
TexPic = CTexture::s_ptexBackBufferScaled[2];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$HDR_BackBuffer"))
|
|
{
|
|
TexPic = CTexture::s_ptexSceneTarget;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$HDR_BackBufferScaled_d2"))
|
|
{
|
|
TexPic = CTexture::s_ptexHDRTargetScaled[0];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$HDR_BackBufferScaled_d4"))
|
|
{
|
|
TexPic = CTexture::s_ptexHDRTargetScaled[1];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$HDR_BackBufferScaled_d8"))
|
|
{
|
|
TexPic = CTexture::s_ptexHDRTargetScaled[2];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$HDR_FinalBloom"))
|
|
{
|
|
TexPic = CTexture::s_ptexHDRFinalBloom;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$HDR_TargetPrev"))
|
|
{
|
|
TexPic = CTexture::s_ptexHDRTargetPrev;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$HDR_AverageLuminance"))
|
|
{
|
|
TexPic = CTexture::s_ptexHDRMeasuredLuminanceDummy;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$ZTarget"))
|
|
{
|
|
TexPic = CTexture::s_ptexZTarget;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$ZTargetScaled"))
|
|
{
|
|
TexPic = CTexture::s_ptexZTargetScaled;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$ZTargetScaled2"))
|
|
{
|
|
TexPic = CTexture::s_ptexZTargetScaled2;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SceneTarget"))
|
|
{
|
|
TexPic = CTexture::s_ptexSceneTarget;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$CloudsLM"))
|
|
{
|
|
TexPic = CTexture::s_ptexCloudsLM;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$WaterVolumeDDN"))
|
|
{
|
|
TexPic = CTexture::s_ptexWaterVolumeDDN;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$WaterVolumeReflPrev"))
|
|
{
|
|
TexPic = CTexture::s_ptexWaterVolumeRefl[1];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$WaterVolumeRefl"))
|
|
{
|
|
TexPic = CTexture::s_ptexWaterVolumeRefl[0];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$WaterVolumeCaustics"))
|
|
{
|
|
TexPic = CTexture::s_ptexWaterCaustics[0];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$WaterVolumeCausticsTemp"))
|
|
{
|
|
TexPic = CTexture::s_ptexWaterCaustics[1];
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SceneNormalsMap"))
|
|
{
|
|
TexPic = CTexture::s_ptexSceneNormalsMap;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SceneNormalsMapMS"))
|
|
{
|
|
TexPic = CTexture::s_ptexSceneNormalsMapMS;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SceneDiffuse"))
|
|
{
|
|
TexPic = CTexture::s_ptexSceneDiffuse;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SceneSpecular"))
|
|
{
|
|
TexPic = CTexture::s_ptexSceneSpecular;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SceneNormalsBent"))
|
|
{
|
|
TexPic = CTexture::s_ptexSceneNormalsBent;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SceneDiffuseAcc"))
|
|
{
|
|
TexPic = CTexture::s_ptexCurrentSceneDiffuseAccMap;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SceneSpecularAcc"))
|
|
{
|
|
TexPic = CTexture::s_ptexSceneSpecularAccMap;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SceneDiffuseAccMS"))
|
|
{
|
|
TexPic = CTexture::s_ptexSceneDiffuseAccMapMS;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$SceneSpecularAccMS"))
|
|
{
|
|
TexPic = CTexture::s_ptexSceneSpecularAccMapMS;
|
|
}
|
|
else
|
|
if (!azstricmp(mapname, "$DefaultEnvironmentProbe"))
|
|
{
|
|
TexPic = CTexture::s_defaultEnvironmentProbeDummy;
|
|
}
|
|
|
|
return TexPic;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// [Shader System TO DO] - remove and replace with data driven from the shader files
|
|
//------------------------------------------------------------------------------
|
|
const char* CShaderMan::mfTemplateTexIdToName(int Id)
|
|
{
|
|
switch (Id)
|
|
{
|
|
case EFTT_DIFFUSE:
|
|
return "Diffuse";
|
|
case EFTT_SPECULAR:
|
|
return "Gloss";
|
|
case EFTT_NORMALS:
|
|
return "Bump";
|
|
case EFTT_ENV:
|
|
return "Environment";
|
|
case EFTT_SUBSURFACE:
|
|
return "SubSurface";
|
|
case EFTT_CUSTOM:
|
|
return "CustomMap";
|
|
case EFTT_CUSTOM_SECONDARY:
|
|
return "CustomSecondaryMap";
|
|
case EFTT_DETAIL_OVERLAY:
|
|
return "Detail";
|
|
case EFTT_OPACITY:
|
|
return "Opacity";
|
|
case EFTT_DECAL_OVERLAY:
|
|
return "Decal";
|
|
case EFTT_OCCLUSION:
|
|
return "Occlusion";
|
|
case EFTT_SPECULAR_2:
|
|
return "Specular2";
|
|
case EFTT_SMOOTHNESS:
|
|
return "GlossNormalA";
|
|
case EFTT_EMITTANCE:
|
|
return "Emittance";
|
|
default:
|
|
return "Unknown";
|
|
}
|
|
}
|
|
|
|
CTexAnim* CShaderMan::mfReadTexSequence(const char* na, int Flags, [[maybe_unused]] bool bFindOnly)
|
|
{
|
|
char prefix[_MAX_PATH];
|
|
char postfix[_MAX_PATH];
|
|
char* nm;
|
|
int i, j, l, m;
|
|
char nam[_MAX_PATH];
|
|
int n;
|
|
CTexture* tx, * tp;
|
|
int startn, endn, nums;
|
|
char name[_MAX_PATH];
|
|
|
|
tx = NULL;
|
|
|
|
cry_strcpy(name, na);
|
|
const char* ext = fpGetExtension (na);
|
|
fpStripExtension(name, name);
|
|
|
|
char chSep = '#';
|
|
nm = strchr(name, chSep);
|
|
if (!nm)
|
|
{
|
|
nm = strchr(name, '$');
|
|
if (!nm)
|
|
{
|
|
return 0;
|
|
}
|
|
chSep = '$';
|
|
}
|
|
|
|
float fSpeed = 0.05f;
|
|
{
|
|
char nName[_MAX_PATH];
|
|
azstrcpy(nName, _MAX_PATH, name);
|
|
nm = strchr(nName, '(');
|
|
if (nm)
|
|
{
|
|
name[nm - nName] = 0;
|
|
char* speed = &nName[nm - nName + 1];
|
|
nm = strchr(speed, ')');
|
|
if (nm)
|
|
{
|
|
speed[nm - speed] = 0;
|
|
}
|
|
fSpeed = (float)atof(speed);
|
|
}
|
|
}
|
|
|
|
j = 0;
|
|
n = 0;
|
|
l = -1;
|
|
m = -1;
|
|
while (name[n])
|
|
{
|
|
if (name[n] == chSep)
|
|
{
|
|
j++;
|
|
if (l == -1)
|
|
{
|
|
l = n;
|
|
}
|
|
}
|
|
else
|
|
if (l >= 0 && m < 0)
|
|
{
|
|
m = n;
|
|
}
|
|
n++;
|
|
}
|
|
if (!j)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
cry_strcpy(prefix, name, l);
|
|
|
|
char dig[_MAX_PATH];
|
|
l = 0;
|
|
if (m < 0)
|
|
{
|
|
startn = 0;
|
|
endn = 999;
|
|
postfix[0] = 0;
|
|
}
|
|
else
|
|
{
|
|
while (isdigit((unsigned char)name[m]))
|
|
{
|
|
dig[l++] = name[m];
|
|
m++;
|
|
}
|
|
dig[l] = 0;
|
|
startn = strtol(dig, NULL, 10);
|
|
m++;
|
|
|
|
l = 0;
|
|
while (isdigit((unsigned char)name[m]))
|
|
{
|
|
dig[l++] = name[m];
|
|
m++;
|
|
}
|
|
dig[l] = 0;
|
|
endn = strtol(dig, NULL, 10);
|
|
|
|
azstrcpy(postfix, AZ_ARRAY_SIZE(postfix), &name[m]);
|
|
}
|
|
|
|
nums = endn - startn + 1;
|
|
|
|
n = 0;
|
|
char frm[256];
|
|
char frd[4];
|
|
|
|
frd[0] = j + '0';
|
|
frd[1] = 0;
|
|
|
|
cry_strcpy(frm, "%s%.");
|
|
cry_strcat(frm, frd);
|
|
cry_strcat(frm, "d%s%s");
|
|
CTexAnim* ta = NULL;
|
|
for (i = 0; i < nums; i++)
|
|
{
|
|
sprintf_s(nam, frm, prefix, startn + i, postfix, ext);
|
|
tp = (CTexture*)gRenDev->EF_LoadTexture(nam, Flags);
|
|
if (!tp || !tp->IsLoaded())
|
|
{
|
|
if (tp)
|
|
{
|
|
tp->Release();
|
|
}
|
|
break;
|
|
}
|
|
if (!ta)
|
|
{
|
|
ta = new CTexAnim;
|
|
ta->m_bLoop = true;
|
|
ta->m_Time = fSpeed;
|
|
}
|
|
|
|
ta->m_TexPics.AddElem(tp);
|
|
n++;
|
|
}
|
|
|
|
if (ta)
|
|
{
|
|
ta->m_NumAnimTexs = ta->m_TexPics.Num();
|
|
}
|
|
|
|
return ta;
|
|
}
|
|
|
|
int CShaderMan::mfReadTexSequence(STexSamplerRT *smp, const char *na, int Flags, bool bFindOnly)
|
|
{
|
|
if (smp->m_pAnimInfo)
|
|
{
|
|
assert(0);
|
|
return 0;
|
|
}
|
|
|
|
CTexAnim* ta = mfReadTexSequence(na, Flags, bFindOnly);
|
|
if (ta)
|
|
{
|
|
smp->m_pAnimInfo = ta;
|
|
SAFE_RELEASE(smp->m_pTex);
|
|
return ta->m_NumAnimTexs;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CShaderMan::mfSetResourceTexState(SEfResTexture* Tex)
|
|
{
|
|
if (Tex)
|
|
{
|
|
STexState ST;
|
|
ST.SetFilterMode(Tex->m_Filter);
|
|
ST.SetClampMode(Tex->m_bUTile ? TADDR_WRAP : TADDR_CLAMP, Tex->m_bVTile ? TADDR_WRAP : TADDR_CLAMP, Tex->m_bUTile ? TADDR_WRAP : TADDR_CLAMP);
|
|
Tex->m_Sampler.m_nTexState = CTexture::GetTexState(ST);
|
|
}
|
|
}
|
|
|
|
CTexture* CShaderMan::mfTryToLoadTexture(const char* nameTex, STexSamplerRT* smp, int Flags, bool bFindOnly)
|
|
{
|
|
CTexture* tx = NULL;
|
|
if (nameTex && strchr(nameTex, '#')) // test for " #" to skip max material names
|
|
{
|
|
int n = mfReadTexSequence(smp, nameTex, Flags, bFindOnly);
|
|
//If we were able to read the texture animation, those textures will all be loaded and set into smp->m_pAnimInfo->m_TexPics by mfReadTexSequence.
|
|
//Other code is dependent on some texture being returned here though, so Just return the first one in the animation.
|
|
if (n > 0 && smp->m_pAnimInfo && !smp->m_pAnimInfo->m_TexPics.empty())
|
|
{
|
|
smp->m_pAnimInfo->m_TexPics[0]->AddRef();
|
|
return smp->m_pAnimInfo->m_TexPics[0];
|
|
}
|
|
}
|
|
if (!tx)
|
|
{
|
|
if (bFindOnly)
|
|
{
|
|
tx = (CTexture*)gRenDev->EF_GetTextureByName(nameTex, Flags);
|
|
}
|
|
else
|
|
{
|
|
tx = (CTexture*)gRenDev->EF_LoadTexture(nameTex, Flags);
|
|
}
|
|
}
|
|
|
|
return tx;
|
|
}
|
|
|
|
CTexture* CShaderMan::mfFindResourceTexture(const char* nameTex, [[maybe_unused]] const char* path, int Flags, SEfResTexture* Tex)
|
|
{
|
|
mfSetResourceTexState(Tex);
|
|
|
|
return mfTryToLoadTexture(nameTex, Tex ? &Tex->m_Sampler : NULL, Flags, true);
|
|
}
|
|
|
|
CTexture* CShaderMan::mfLoadResourceTexture(const char* nameTex, [[maybe_unused]] const char* path, int Flags, SEfResTexture* Tex)
|
|
{
|
|
mfSetResourceTexState(Tex);
|
|
|
|
return mfTryToLoadTexture(nameTex, Tex ? &Tex->m_Sampler : NULL, Flags, false);
|
|
}
|
|
|
|
|
|
bool CShaderMan::mfLoadResourceTexture(ResourceSlotIndex Id, SInputShaderResources& RS, uint32 CustomFlags, bool bReplaceMeOnFail)
|
|
{
|
|
SEfResTexture* pTextureRes = RS.GetTextureResource(Id);
|
|
|
|
if (!pTextureRes || pTextureRes->m_Name.empty())
|
|
return false;
|
|
|
|
// Texture slot and texture name exist
|
|
STexSamplerRT& texSampler(pTextureRes->m_Sampler);
|
|
|
|
// No texture or texture not loaded - try to load it
|
|
if (!texSampler.m_pTex || !texSampler.m_pTex->IsTextureLoaded())
|
|
{
|
|
texSampler.m_pTex = mfLoadResourceTexture( pTextureRes->m_Name.c_str(), RS.m_TexturePath.c_str(), texSampler.GetTexFlags() | CustomFlags, pTextureRes);
|
|
}
|
|
|
|
bool bTextureLoadSuccess = texSampler.m_pTex->IsTextureLoaded();
|
|
// Texture was not successfully loaded but is marked for placeholder loading on fail
|
|
if (!bTextureLoadSuccess && bReplaceMeOnFail)
|
|
{
|
|
texSampler.m_pTex = mfLoadResourceTexture( szReplaceMe, RS.m_TexturePath.c_str(), texSampler.GetTexFlags() | CustomFlags, pTextureRes);
|
|
}
|
|
return bTextureLoadSuccess;
|
|
}
|
|
|
|
bool CShaderMan::mfLoadResourceTexture(ResourceSlotIndex Id, CShaderResources& RS, uint32 CustomFlags, bool bReplaceMeOnFail)
|
|
{
|
|
SEfResTexture* pTextureRes = RS.GetTextureResource(Id);
|
|
|
|
// Texture slot does not exist
|
|
if (!pTextureRes)
|
|
return false;
|
|
|
|
STexSamplerRT& texSampler(pTextureRes->m_Sampler);
|
|
bool bTextureLoaded = texSampler.m_pTex && texSampler.m_pTex->IsTextureLoaded();
|
|
|
|
if (!pTextureRes->m_Name.empty())
|
|
{ // texture can be retrieved
|
|
if (!bTextureLoaded || (CustomFlags & FT_ALPHA))
|
|
{
|
|
SAFE_RELEASE(texSampler.m_pTex);
|
|
texSampler.m_pTex = mfLoadResourceTexture(pTextureRes->m_Name.c_str(), RS.m_TexturePath.c_str(), texSampler.GetTexFlags() | CustomFlags, pTextureRes);
|
|
}
|
|
|
|
if (!bTextureLoaded && texSampler.m_pTex->IsTextureMissing())
|
|
{
|
|
TextureWarning(pTextureRes->m_Name.c_str(), "Texture file is missing: '%s%s' in material \'%s\'", RS.m_TexturePath.c_str(), pTextureRes->m_Name.c_str(), RS.m_szMaterialName);
|
|
}
|
|
|
|
bTextureLoaded = texSampler.m_pTex->IsTextureLoaded();
|
|
if (!bTextureLoaded && bReplaceMeOnFail)
|
|
{
|
|
texSampler.m_pTex = mfLoadResourceTexture("EngineAssets/TextureMsg/ReplaceMe.tif", RS.m_TexturePath.c_str(), texSampler.GetTexFlags() | CustomFlags, pTextureRes);
|
|
}
|
|
}
|
|
|
|
return bTextureLoaded;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Notice - the function will actively add the marked slot if it does not exist.
|
|
//------------------------------------------------------------------------------
|
|
void CShaderMan::mfLoadDefaultTexture(ResourceSlotIndex Id, CShaderResources& RS, EEfResTextures Def)
|
|
{
|
|
RS.m_TexturesResourcesMap[Id].m_Sampler.m_pTex = TextureHelpers::LookupTexDefault(Def);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Mark refresh required if any texture slot contains a texture
|
|
bool CShaderMan::mfRefreshResourceConstants(CShaderResources* Res)
|
|
{
|
|
if (!Res)
|
|
return false;
|
|
|
|
for (auto iter = Res->m_TexturesResourcesMap.begin(); iter != Res->m_TexturesResourcesMap.end(); ++iter)
|
|
{
|
|
SEfResTexture* pTexture = &iter->second;
|
|
if (pTexture->m_Sampler.m_pTex)
|
|
{ // marked changed if the sampler contains pointer to a texture
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// [Shader System] - TO DO : be very careful when optimizing this as it can lead
|
|
// to loss / uncorrelated of texture slots.
|
|
//------------------------------------------------------------------------------
|
|
void CShaderMan::mfRefreshResources(CShaderResources* Res)
|
|
{
|
|
if (Res)
|
|
{
|
|
for (int i = 0; i < EFTT_MAX; i++)
|
|
{
|
|
int Flags = 0;
|
|
if (i == EFTT_NORMALS)
|
|
{
|
|
if ((!Res->TextureSlotExists(i) || Res->m_TexturesResourcesMap[i].m_Name.empty()))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Flags |= FT_TEX_NORMAL_MAP;
|
|
if (!Res->TextureSlotExists(i)) // add a slot
|
|
{
|
|
Res->m_TexturesResourcesMap[i].Cleanup();
|
|
}
|
|
|
|
if (!mfLoadResourceTexture((EEfResTextures)i, *Res, Flags))
|
|
{
|
|
mfLoadDefaultTexture((EEfResTextures)i, *Res, (EEfResTextures)i);
|
|
}
|
|
|
|
// Support for gloss in regular normal map
|
|
CTexture* pTexN = (Res->TextureSlotExists(i) ? Res->m_TexturesResourcesMap[i].m_Sampler.m_pTex : NULL);
|
|
if (pTexN && (pTexN->GetFlags() & FT_HAS_ATTACHED_ALPHA))
|
|
{
|
|
Res->m_TexturesResourcesMap[EFTT_SMOOTHNESS].m_Name = pTexN->GetSourceName();
|
|
if (!mfLoadResourceTexture(EFTT_SMOOTHNESS, *Res, Flags | FT_ALPHA))
|
|
{
|
|
mfLoadDefaultTexture(EFTT_SMOOTHNESS, *Res, (EEfResTextures)i);
|
|
}
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else
|
|
if (i == EFTT_HEIGHT)
|
|
{
|
|
if (!Res->TextureSlotExists(EFTT_NORMALS) || !Res->m_TexturesResourcesMap[EFTT_NORMALS].m_Sampler.m_pTex)
|
|
{
|
|
continue;
|
|
}
|
|
if (!Res->TextureSlotExists(i))
|
|
{
|
|
continue; //Res->AddTextureMap(i);
|
|
}
|
|
mfLoadResourceTexture((EEfResTextures)i, *Res, Flags);
|
|
}
|
|
else
|
|
if (i == EFTT_CUSTOM_SECONDARY)
|
|
{
|
|
if ((!Res->TextureSlotExists(i) || Res->m_TexturesResourcesMap[i].m_Name.empty()))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!Res->TextureSlotExists(i))
|
|
{ // adds the slot
|
|
Res->m_TexturesResourcesMap[i].Cleanup();
|
|
}
|
|
|
|
if (!mfLoadResourceTexture((EEfResTextures)i, *Res, Flags))
|
|
{
|
|
mfLoadDefaultTexture((EEfResTextures)i, *Res, (EEfResTextures)i);
|
|
}
|
|
|
|
// Support for gloss in blend layer normal map
|
|
CTexture* pTexN = (Res->TextureSlotExists(i) ? Res->m_TexturesResourcesMap[i].m_Sampler.m_pTex : NULL);
|
|
if (pTexN && (pTexN->GetFlags() & FT_HAS_ATTACHED_ALPHA))
|
|
{
|
|
Res->m_TexturesResourcesMap[EFTT_SECOND_SMOOTHNESS].m_Name = pTexN->GetSourceName();
|
|
if (!mfLoadResourceTexture(EFTT_SECOND_SMOOTHNESS, *Res, Flags | FT_ALPHA))
|
|
{
|
|
mfLoadDefaultTexture(EFTT_SECOND_SMOOTHNESS, *Res, EFTT_SMOOTHNESS);
|
|
}
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
SEfResTexture* Tex = Res->GetTextureResource(i);
|
|
if (!Tex)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// TODO: fix this bug at the root, a texture is allocated even though "nearest_cubemap"-named textures should be NULL
|
|
if (Tex->m_Sampler.m_eTexType == eTT_NearestCube)
|
|
{
|
|
SAFE_RELEASE(Tex->m_Sampler.m_pTex);
|
|
Tex->m_Sampler.m_pTex = CTexture::s_ptexFromObjCM;
|
|
}
|
|
|
|
if (!Tex->m_Sampler.m_pTex)
|
|
{
|
|
if (Tex->m_Sampler.m_eTexType == eTT_NearestCube)
|
|
{
|
|
Tex->m_Sampler.m_pTex = CTexture::s_ptexFromObjCM;
|
|
}
|
|
else
|
|
if (Tex->m_Sampler.m_eTexType == eTT_Dyn2D)
|
|
{
|
|
// This block was for loading Flash files
|
|
}
|
|
else
|
|
if (Tex->m_Sampler.m_eTexType == eTT_Auto2D)
|
|
{
|
|
if (i == EFTT_ENV)
|
|
{
|
|
mfSetResourceTexState(Tex);
|
|
|
|
SAFE_RELEASE(Tex->m_Sampler.m_pTarget);
|
|
Tex->m_Sampler.m_pTarget = new SHRenderTarget;
|
|
|
|
Tex->m_Sampler.m_pTex = CTexture::s_ptexRT_2D;
|
|
Tex->m_Sampler.m_pTarget->m_pTarget[0] = CTexture::s_ptexRT_2D;
|
|
|
|
Tex->m_Sampler.m_pTarget->m_bTempDepth = true;
|
|
Tex->m_Sampler.m_pTarget->m_eOrder = eRO_PreProcess;
|
|
Tex->m_Sampler.m_pTarget->m_eTF = eTF_R8G8B8A8;
|
|
Tex->m_Sampler.m_pTarget->m_nIDInPool = -1;
|
|
Tex->m_Sampler.m_pTarget->m_nFlags |= FRT_RENDTYPE_RECURSIVECURSCENE | FRT_CAMERA_CURRENT;
|
|
Tex->m_Sampler.m_pTarget->m_nFlags |= FRT_CLEAR_DEPTH | FRT_CLEAR_STENCIL | FRT_CLEAR_COLOR;
|
|
}
|
|
}
|
|
else
|
|
if (Tex->m_Sampler.m_eTexType == eTT_User)
|
|
{
|
|
Tex->m_Sampler.m_pTex = NULL;
|
|
}
|
|
else
|
|
{
|
|
mfLoadResourceTexture((EEfResTextures)i, *Res, Flags);
|
|
}
|
|
}
|
|
|
|
// assign streaming priority based on the importance (sampler slot)
|
|
if (Tex && Tex->m_Sampler.m_pITex && Tex->m_Sampler.m_pITex->IsTextureLoaded() && Tex->m_Sampler.m_pITex->IsStreamedVirtual())
|
|
{
|
|
CTexture* tp = (CTexture*)Tex->m_Sampler.m_pITex;
|
|
tp->SetStreamingPriority(EFTT_MAX - i);
|
|
}
|
|
}
|
|
}
|
|
|
|
mfRefreshResourceConstants(Res);
|
|
}
|