BVB Source Codes

CRYENGINE Show Material.cpp Source code

Return Download CRYENGINE: download Material.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  File name:   Material.cpp
  5. //  Version:     v1.00
  6. //  Created:     3/9/2004 by Timur.
  7. //  Compilers:   Visual Studio.NET 2003
  8. //  Description:
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15. #include "MatMan.h"
  16. #include <CryRenderer/IRenderer.h>
  17. #include "VisAreas.h"
  18.  
  19. DEFINE_INTRUSIVE_LINKED_LIST(CMatInfo)
  20.  
  21. //////////////////////////////////////////////////////////////////////////
  22. void CMaterialLayer::SetShaderItem(const IMaterial* pParentMtl, const SShaderItem& pShaderItem)
  23. {
  24.         assert(pParentMtl && "CMaterialLayer::SetShaderItem invalid material");
  25.  
  26.         if (pShaderItem.m_pShader)
  27.         {
  28.                 pShaderItem.m_pShader->AddRef();
  29.         }
  30.  
  31.         if (pShaderItem.m_pShaderResources)
  32.         {
  33.                 pShaderItem.m_pShaderResources->AddRef();
  34.                 CMatInfo* pParentMatInfo = (CMatInfo*)(const_cast<IMaterial*>(pParentMtl));
  35.                 pShaderItem.m_pShaderResources->SetMaterialName(pParentMatInfo->m_sUniqueMaterialName);
  36.         }
  37.  
  38.         SAFE_RELEASE(m_pShaderItem.m_pShader);
  39.         SAFE_RELEASE(m_pShaderItem.m_pShaderResources);
  40.  
  41.         m_pShaderItem = pShaderItem;
  42.         gEnv->pRenderer->UpdateShaderItem(&m_pShaderItem, NULL);
  43.  
  44. }
  45. //////////////////////////////////////////////////////////////////////////
  46. void CMaterialLayer::GetMemoryUsage(ICrySizer* pSizer)
  47. {
  48.         SIZER_COMPONENT_NAME(pSizer, "MaterialLayer");
  49.         pSizer->AddObject(this, sizeof(*this));
  50. }
  51.  
  52. //////////////////////////////////////////////////////////////////////////
  53. size_t CMaterialLayer::GetResourceMemoryUsage(ICrySizer* pSizer)
  54. {
  55.         size_t nResourceMemory(0);
  56.         // Pushing some context to use the Macro.
  57.         {
  58.                 SIZER_COMPONENT_NAME(pSizer, "Textures");
  59.  
  60.                 IRenderShaderResources* piResources(m_pShaderItem.m_pShaderResources);
  61.                 if (piResources)
  62.                 {
  63.                         //////////////////////////////////////////////////////////////////////////
  64.                         // Texture
  65.                         for (size_t nCount = 0; nCount < EFTT_MAX; ++nCount)
  66.                         {
  67.                                 SEfResTexture* piTextureResource(piResources->GetTexture(nCount));
  68.                                 if (piTextureResource)
  69.                                 {
  70.                                         ITexture* piTexture = piTextureResource->m_Sampler.m_pITex;
  71.                                         if (piTexture)
  72.                                         {
  73.                                                 SIZER_COMPONENT_NAME(pSizer, "MemoryTexture");
  74.                                                 size_t nCurrentResourceMemoryUsage = piTexture->GetDataSize();
  75.                                                 nResourceMemory += nCurrentResourceMemoryUsage;
  76.                                                 pSizer->AddObject(piTexture, nCurrentResourceMemoryUsage);
  77.  
  78.                                                 IResourceCollector* pColl = pSizer->GetResourceCollector();
  79.                                                 if (pColl)
  80.                                                 {
  81.                                                         pColl->AddResource(piTexture->GetName(), nCurrentResourceMemoryUsage);
  82.                                                 }
  83.                                         }
  84.                                 }
  85.                         }
  86.                         //////////////////////////////////////////////////////////////////////////
  87.                 }
  88.         }
  89.         return nResourceMemory;
  90. }
  91.  
  92. //////////////////////////////////////////////////////////////////////////
  93. CMatInfo::CMatInfo()
  94.         : m_bDeleted(false)
  95. {
  96.         m_nRefCount = 1; // having a pointer to CMatInfo with ref count zero, results in CMatInfo being deleted from render thread
  97.         m_Flags = 0;
  98.         m_nModificationId = 0;
  99.  
  100.         m_nSurfaceTypeId = 0;
  101.  
  102.         m_pMaterialLayers = 0;
  103.  
  104.         m_ucDefautMappingAxis = 0;
  105.         m_fDefautMappingScale = 1.f;
  106.  
  107. #ifdef SUPPORT_MATERIAL_SKETCH
  108.         m_pPreSketchShader = 0;
  109.         m_nPreSketchTechnique = 0;
  110. #endif
  111.  
  112. #ifdef SUPPORT_MATERIAL_EDITING
  113.         m_pUserData = NULL;
  114. #endif
  115.  
  116.         m_pActiveLayer = NULL;
  117.  
  118.         ZeroStruct(m_streamZoneInfo);
  119.  
  120. #ifdef TRACE_MATERIAL_LEAKS
  121.         m_sLoadingCallstack = GetSystem()->GetLoadingProfilerCallstack();
  122. #endif
  123.  
  124. #if defined(ENABLE_CONSOLE_MTL_VIZ)
  125.         m_pConsoleMtl = 0;
  126. #endif
  127. }
  128.  
  129. //////////////////////////////////////////////////////////////////////////
  130. CMatInfo::~CMatInfo()
  131. {
  132.         ShutDown();
  133. }
  134.  
  135. void CMatInfo::AddRef()
  136. {
  137.         CryInterlockedIncrement(&m_nRefCount);
  138. }
  139.  
  140. //////////////////////////////////////////////////////////////////////////
  141. void CMatInfo::Release()
  142. {
  143.         if (CryInterlockedDecrement(&m_nRefCount) == 0)
  144.         {
  145.                 if (!(m_Flags & MTL_FLAG_DELETE_PENDING) && GetMatMan())
  146.                 {
  147.                         m_Flags |= MTL_FLAG_DELETE_PENDING;
  148.                         ((CMatMan*)GetMatMan())->Unregister(this);
  149.                         ((CMatMan*)GetMatMan())->DelayedDelete(this);
  150.                 }
  151.                 else
  152.                 {
  153.                         delete this;
  154.                 }
  155.         }
  156. }
  157.  
  158. //////////////////////////////////////////////////////////////////////////
  159. void CMatInfo::ShutDown()
  160. {
  161.         if (!m_bDeleted)
  162.         {
  163.                 SAFE_DELETE(m_pMaterialLayers);
  164.  
  165.                 if (m_shaderItem.m_pShaderResources)
  166.                 {
  167.                         CCamera* pC = m_shaderItem.m_pShaderResources->GetCamera();
  168.                         if (pC)
  169.                                 delete pC;
  170.                 }
  171.                 SAFE_RELEASE(m_shaderItem.m_pShader);
  172.                 SAFE_RELEASE(m_shaderItem.m_pShaderResources);
  173.  
  174.                 if (GetMatMan() && !(m_Flags & MTL_FLAG_DELETE_PENDING))
  175.                         ((CMatMan*)GetMatMan())->Unregister(this);
  176.  
  177.                 m_subMtls.clear();
  178.         }
  179.         m_bDeleted = true;
  180. }
  181.  
  182. //////////////////////////////////////////////////////////////////////////
  183. IMaterialHelpers& CMatInfo::GetMaterialHelpers()
  184. {
  185.         return GetMatMan()->s_materialHelpers;
  186. }
  187.  
  188. IMaterialManager* CMatInfo::GetMaterialManager()
  189. {
  190.         return GetMatMan();
  191. }
  192.  
  193. //////////////////////////////////////////////////////////////////////////
  194. void CMatInfo::SetName(const char* sName)
  195. {
  196.         m_sMaterialName = sName;
  197.         m_sUniqueMaterialName = m_sMaterialName;
  198.         if (m_shaderItem.m_pShaderResources)
  199.                 m_shaderItem.m_pShaderResources->SetMaterialName(m_sUniqueMaterialName); // Only for correct warning message purposes.
  200.         if (m_Flags & MTL_FLAG_MULTI_SUBMTL)
  201.         {
  202.                 for (int i = 0, num = m_subMtls.size(); i < num; i++)
  203.                 {
  204.                         if (m_subMtls[i] && (m_subMtls[i]->m_Flags & MTL_FLAG_PURE_CHILD))
  205.                         {
  206.                                 m_subMtls[i]->m_sUniqueMaterialName = m_sMaterialName;
  207.                                 if (m_subMtls[i]->m_shaderItem.m_pShaderResources)
  208.                                         m_subMtls[i]->m_shaderItem.m_pShaderResources->SetMaterialName(m_sUniqueMaterialName);
  209.                         }
  210.  
  211.                         if (m_subMtls[i] && strstr(m_subMtls[i]->m_sUniqueMaterialName, MTL_SPECIAL_NAME_RAYCAST_PROXY) != 0)
  212.                         {
  213.                                 m_subMtls[i]->m_Flags |= MTL_FLAG_RAYCAST_PROXY;
  214.                                 m_subMtls[i]->m_Flags |= MTL_FLAG_NODRAW;
  215.                         }
  216.                 }
  217.         }
  218.  
  219.         if (strstr(sName, MTL_SPECIAL_NAME_COLLISION_PROXY) != 0 || strstr(sName, MTL_SPECIAL_NAME_COLLISION_PROXY_VEHICLE) != 0)
  220.         {
  221.                 m_Flags |= MTL_FLAG_COLLISION_PROXY;
  222.         }
  223.         else if (strstr(sName, MTL_SPECIAL_NAME_RAYCAST_PROXY) != 0)
  224.         {
  225.                 m_Flags |= MTL_FLAG_RAYCAST_PROXY;
  226.                 m_Flags |= MTL_FLAG_NODRAW;
  227.         }
  228. }
  229.  
  230. //////////////////////////////////////////////////////////////////////////
  231. bool CMatInfo::IsDefault()
  232. {
  233.         return this == GetMatMan()->GetDefaultMaterial();
  234. }
  235.  
  236. //////////////////////////////////////////////////////////////////////////
  237. void CMatInfo::UpdateMaterialFlags()
  238. {
  239.         m_Flags &= ~(MTL_FLAG_REQUIRE_FORWARD_RENDERING | MTL_FLAG_REQUIRE_NEAREST_CUBEMAP);
  240.  
  241.         if (m_shaderItem.m_pShader)
  242.         {
  243.                 IRenderShaderResources* pRendShaderResources = m_shaderItem.m_pShaderResources;
  244.  
  245.                 const bool bAlphaBlended = (m_shaderItem.m_pShader->GetFlags() & (EF_NODRAW | EF_DECAL)) || (pRendShaderResources && pRendShaderResources->IsTransparent());
  246.                 const bool bIsHair = (m_shaderItem.m_pShader->GetFlags2() & EF2_HAIR) != 0;
  247.                 const bool bIsGlass = m_shaderItem.m_pShader->GetShaderType() == eST_Glass;
  248.  
  249.                 if (bAlphaBlended && !(m_shaderItem.m_pShader->GetFlags2() & EF2_NODRAW) && !(m_shaderItem.m_pShader->GetFlags() & EF_DECAL))
  250.                 {
  251.                         m_Flags |= MTL_FLAG_REQUIRE_FORWARD_RENDERING;
  252.                 }
  253.                 else if (bIsHair || bIsGlass)
  254.                 {
  255.                         m_Flags |= MTL_FLAG_REQUIRE_FORWARD_RENDERING;
  256.                 }
  257.  
  258.                 if ((bAlphaBlended || bIsHair || bIsGlass) &&
  259.                     (pRendShaderResources) &&
  260.                     (pRendShaderResources->GetTexture(EFTT_ENV)) &&
  261.                     (pRendShaderResources->GetTexture(EFTT_ENV)->m_Sampler.m_eTexType == eTT_NearestCube))
  262.                 {
  263.                         m_Flags |= MTL_FLAG_REQUIRE_NEAREST_CUBEMAP;
  264.                 }
  265.  
  266.                 // Make sure to refresh sectors
  267.                 static int nLastUpdateFrameId = 0;
  268.                 if (gEnv->IsEditing() && GetTerrain() && GetVisAreaManager() && nLastUpdateFrameId != GetRenderer()->GetFrameID())
  269.                 {
  270.                         GetTerrain()->MarkAllSectorsAsUncompiled(0);
  271.                         GetVisAreaManager()->MarkAllSectorsAsUncompiled();
  272.                         nLastUpdateFrameId = GetRenderer()->GetFrameID();
  273.                 }
  274.         }
  275. }
  276.  
  277. //////////////////////////////////////////////////////////////////////////
  278. void CMatInfo::SetShaderItem(const SShaderItem& _ShaderItem)
  279. {
  280.         if (_ShaderItem.m_pShader)
  281.                 _ShaderItem.m_pShader->AddRef();
  282.         if (_ShaderItem.m_pShaderResources)
  283.         {
  284.                 _ShaderItem.m_pShaderResources->AddRef();
  285.                 _ShaderItem.m_pShaderResources->SetMaterialName(m_sUniqueMaterialName);
  286.         }
  287.  
  288.         SAFE_RELEASE(m_shaderItem.m_pShader);
  289.         SAFE_RELEASE(m_shaderItem.m_pShaderResources);
  290.  
  291.         m_shaderItem = _ShaderItem;
  292.         gEnv->pRenderer->UpdateShaderItem(&m_shaderItem, this);
  293.         IncrementModificationId();
  294.  
  295.         UpdateMaterialFlags();
  296.  
  297.         int sketchMode = m_pMatMan->GetSketchMode();
  298.         if (sketchMode)
  299.                 SetSketchMode(sketchMode);
  300. }
  301.  
  302. //////////////////////////////////////////////////////////////////////////
  303. void CMatInfo::AssignShaderItem(const SShaderItem& _ShaderItem)
  304. {
  305.         //if (_ShaderItem.m_pShader)
  306.         //      _ShaderItem.m_pShader->AddRef();
  307.         if (_ShaderItem.m_pShaderResources)
  308.         {
  309.                 _ShaderItem.m_pShaderResources->SetMaterialName(m_sUniqueMaterialName);
  310.         }
  311.  
  312.         SAFE_RELEASE(m_shaderItem.m_pShader);
  313.         SAFE_RELEASE(m_shaderItem.m_pShaderResources);
  314.  
  315.         m_shaderItem = _ShaderItem;
  316.         gEnv->pRenderer->UpdateShaderItem(&m_shaderItem, this);
  317.         IncrementModificationId();
  318.  
  319.         UpdateMaterialFlags();
  320. }
  321.  
  322. //////////////////////////////////////////////////////////////////////////
  323. void CMatInfo::SetSurfaceType(const char* sSurfaceTypeName)
  324. {
  325.         m_nSurfaceTypeId = 0;
  326.  
  327.         ISurfaceType* pSurfaceType = GetMatMan()->GetSurfaceTypeByName(sSurfaceTypeName, m_sMaterialName);
  328.         if (pSurfaceType)
  329.                 m_nSurfaceTypeId = pSurfaceType->GetId();
  330. }
  331.  
  332. ISurfaceType* CMatInfo::GetSurfaceType()
  333. {
  334.         return GetMatMan()->GetSurfaceType(m_nSurfaceTypeId, m_sMaterialName);
  335. }
  336.  
  337. //////////////////////////////////////////////////////////////////////////
  338. void CMatInfo::SetMatTemplate(const char* sMatTemplate)
  339. {
  340. #ifdef SUPPORT_MATERIAL_EDITING
  341.         m_sMatTemplate = sMatTemplate;
  342. #endif
  343. }
  344.  
  345. IMaterial* CMatInfo::GetMatTemplate()
  346. {
  347. #ifdef SUPPORT_MATERIAL_EDITING
  348.         if (!m_sMatTemplate.empty())
  349.         {
  350.                 return GetMatMan()->LoadMaterial(m_sMatTemplate, false);
  351.         }
  352. #else
  353.         CryFatalError("CMatInfo::GetMatTemplate not supported on this platform");
  354. #endif
  355.  
  356.         return NULL;
  357. }
  358.  
  359. //////////////////////////////////////////////////////////////////////////
  360. void CMatInfo::SetSubMtlCount(int numSubMtl)
  361. {
  362.         AUTO_LOCK(GetSubMaterialResizeLock());
  363.         m_Flags |= MTL_FLAG_MULTI_SUBMTL;
  364.         m_subMtls.resize(numSubMtl);
  365. }
  366.  
  367. //////////////////////////////////////////////////////////////////////////
  368. bool CMatInfo::IsStreamedIn(const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES], IRenderMesh* pRenderMesh) const
  369. {
  370.         if (pRenderMesh)
  371.         {
  372.                 TRenderChunkArray* pChunks = &pRenderMesh->GetChunks();
  373.  
  374.                 if (pChunks != NULL)
  375.                 {
  376.                         for (uint32 i = 0, size = pChunks->size(); i < size; i++)
  377.                         {
  378.                                 if (!AreChunkTexturesStreamedIn(&(*pChunks)[i], nMinPrecacheRoundIds))
  379.                                         return false;
  380.                         }
  381.                 }
  382.  
  383.                 pChunks = &pRenderMesh->GetChunksSkinned();
  384.                 for (uint32 i = 0, size = pChunks->size(); i < size; i++)
  385.                 {
  386.                         if (!AreChunkTexturesStreamedIn(&(*pChunks)[i], nMinPrecacheRoundIds))
  387.                                 return false;
  388.                 }
  389.         }
  390.         else
  391.         {
  392.                 if (!AreChunkTexturesStreamedIn(NULL, nMinPrecacheRoundIds))
  393.                         return false;
  394.         }
  395.  
  396.         return true;
  397. }
  398.  
  399. bool CMatInfo::IsStreamedIn(const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES]) const
  400. {
  401.         if (m_Flags & MTL_FLAG_MULTI_SUBMTL)
  402.         {
  403.                 for (int i = 0, num = m_subMtls.size(); i < num; i++)
  404.                 {
  405.                         if (!m_subMtls[i]->AreTexturesStreamedIn(nMinPrecacheRoundIds))
  406.                         {
  407.                                 return false;
  408.                         }
  409.                 }
  410.  
  411.                 return true;
  412.         }
  413.  
  414.         return AreTexturesStreamedIn(nMinPrecacheRoundIds);
  415. }
  416.  
  417. bool CMatInfo::AreChunkTexturesStreamedIn(CRenderChunk* pRenderChunk, const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES]) const
  418. {
  419.         const CMatInfo* pMaterial = this;
  420.  
  421.         if (pRenderChunk && pRenderChunk->pRE && pRenderChunk->nNumIndices && pRenderChunk->nNumVerts)
  422.         {
  423.                 // chunk is defined and have valid geometry
  424.                 if (pRenderChunk->m_nMatID < (uint16)m_subMtls.size())
  425.                         pMaterial = (CMatInfo*)m_subMtls[pRenderChunk->m_nMatID];
  426.  
  427.                 if (pMaterial != NULL)
  428.                         return pMaterial->AreTexturesStreamedIn(nMinPrecacheRoundIds);
  429.         }
  430.         else if (!pRenderChunk)
  431.         {
  432.                 if (!AreTexturesStreamedIn(nMinPrecacheRoundIds))
  433.                         return false;
  434.  
  435.                 for (int nSubMtl = 0; nSubMtl < (int)m_subMtls.size(); ++nSubMtl)
  436.                 {
  437.                         pMaterial = m_subMtls[nSubMtl];
  438.  
  439.                         if (pMaterial != NULL)
  440.                         {
  441.                                 if (!pMaterial->AreTexturesStreamedIn(nMinPrecacheRoundIds))
  442.                                         return false;
  443.                         }
  444.                 }
  445.         }
  446.  
  447.         return true;
  448. }
  449.  
  450. bool CMatInfo::AreTexturesStreamedIn(const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES]) const
  451. {
  452.         // Check this material
  453.         if (IRenderShaderResources* pShaderResources = GetShaderItem().m_pShaderResources)
  454.         {
  455.                 for (int t = 0; t < EFTT_MAX; t++)
  456.                 {
  457.                         if (SEfResTexture* pTextureResource = pShaderResources->GetTexture(t))
  458.                         {
  459.                                 if (ITexture* pTexture = pTextureResource->m_Sampler.m_pITex)
  460.                                 {
  461.                                         if (!pTexture->IsStreamedIn(nMinPrecacheRoundIds))
  462.                                                 return false;
  463.                                 }
  464.                         }
  465.                 }
  466.         }
  467.  
  468.         return true;
  469. }
  470.  
  471. //////////////////////////////////////////////////////////////////////////
  472. void CMatInfo::SetSubMtl(int nSlot, IMaterial* pMtl)
  473. {
  474.         assert(nSlot >= 0 && nSlot < (int)m_subMtls.size());
  475.         m_subMtls[nSlot] = (CMatInfo*)pMtl;
  476. }
  477.  
  478. //////////////////////////////////////////////////////////////////////////
  479. void CMatInfo::SetLayerCount(uint32 nCount)
  480. {
  481.         if (!m_pMaterialLayers)
  482.         {
  483.                 m_pMaterialLayers = new MatLayers;
  484.         }
  485.  
  486.         m_pMaterialLayers->resize(nCount);
  487. }
  488.  
  489. //////////////////////////////////////////////////////////////////////////
  490. uint32 CMatInfo::GetLayerCount() const
  491. {
  492.         if (m_pMaterialLayers)
  493.         {
  494.                 return (uint32) m_pMaterialLayers->size();
  495.         }
  496.  
  497.         return 0;
  498. }
  499.  
  500. //////////////////////////////////////////////////////////////////////////
  501. void CMatInfo::SetLayer(uint32 nSlot, IMaterialLayer* pLayer)
  502. {
  503.         assert(m_pMaterialLayers);
  504.         assert(nSlot < (uint32) m_pMaterialLayers->size());
  505.  
  506.         if (m_pMaterialLayers && pLayer && nSlot < (uint32) m_pMaterialLayers->size())
  507.                 (*m_pMaterialLayers)[nSlot] = static_cast<CMaterialLayer*>(pLayer);
  508. }
  509.  
  510. //////////////////////////////////////////////////////////////////////////
  511.  
  512. const IMaterialLayer* CMatInfo::GetLayer(uint8 nLayersMask, uint8 nLayersUsageMask) const
  513. {
  514.         if (m_pMaterialLayers && nLayersMask)
  515.         {
  516.                 int nSlotCount = m_pMaterialLayers->size();
  517.                 for (int nSlot = 0; nSlot < nSlotCount; ++nSlot)
  518.                 {
  519.                         CMaterialLayer* pLayer = static_cast<CMaterialLayer*>((*m_pMaterialLayers)[nSlot]);
  520.  
  521.                         if (nLayersMask & (1 << nSlot))
  522.                         {
  523.                                 if (pLayer)
  524.                                 {
  525.                                         m_pActiveLayer = pLayer;
  526.                                         return m_pActiveLayer;
  527.                                 }
  528.  
  529.                                 m_pActiveLayer = 0;
  530.  
  531.                                 return 0;
  532.                         }
  533.                 }
  534.         }
  535.  
  536.         return 0;
  537. }
  538.  
  539. //////////////////////////////////////////////////////////////////////////
  540. const IMaterialLayer* CMatInfo::GetLayer(uint32 nSlot) const
  541. {
  542.         if (m_pMaterialLayers && nSlot < (uint32) m_pMaterialLayers->size())
  543.                 return static_cast<CMaterialLayer*>((*m_pMaterialLayers)[nSlot]);
  544.  
  545.         return 0;
  546. }
  547.  
  548. //////////////////////////////////////////////////////////////////////////
  549. IMaterialLayer* CMatInfo::CreateLayer()
  550. {
  551.         return new CMaterialLayer;
  552. }
  553.  
  554. //////////////////////////////////////////////////////////////////////////
  555. void CMatInfo::SetUserData(void* pUserData)
  556. {
  557. #ifdef SUPPORT_MATERIAL_EDITING
  558.         m_pUserData = pUserData;
  559. #endif
  560. }
  561.  
  562. //////////////////////////////////////////////////////////////////////////
  563. void* CMatInfo::GetUserData() const
  564. {
  565. #ifdef SUPPORT_MATERIAL_EDITING
  566.         return m_pUserData;
  567. #else
  568.         CryFatalError("CMatInfo::GetUserData not supported on this platform");
  569.         return NULL;
  570. #endif
  571. }
  572.  
  573. //////////////////////////////////////////////////////////////////////////
  574. int CMatInfo::FillSurfaceTypeIds(int pSurfaceIdsTable[])
  575. {
  576.         if (m_subMtls.empty() || !(m_Flags & MTL_FLAG_MULTI_SUBMTL))
  577.         {
  578.                 pSurfaceIdsTable[0] = m_nSurfaceTypeId;
  579.                 return 1; // Not Multi material.
  580.         }
  581.         for (int i = 0; i < (int)m_subMtls.size(); i++)
  582.         {
  583.                 if (m_subMtls[i] != 0)
  584.                         pSurfaceIdsTable[i] = m_subMtls[i]->m_nSurfaceTypeId;
  585.                 else
  586.                         pSurfaceIdsTable[i] = 0;
  587.         }
  588.         return m_subMtls.size();
  589. }
  590.  
  591. void CMatInfo::Copy(IMaterial* pMtlDest, EMaterialCopyFlags flags)
  592. {
  593.         CMatInfo* pMatInfo = static_cast<CMatInfo*>(pMtlDest);
  594.         if (flags & MTL_COPY_NAME)
  595.         {
  596.                 pMatInfo->m_sMaterialName = m_sMaterialName;
  597.                 pMatInfo->m_sUniqueMaterialName = m_sUniqueMaterialName;
  598.         }
  599.         pMatInfo->m_nSurfaceTypeId = m_nSurfaceTypeId;
  600.         pMatInfo->m_Flags = m_Flags;
  601. #ifdef SUPPORT_MATERIAL_EDITING
  602.         if (flags & MTL_COPY_TEMPLATE)
  603.         {
  604.                 pMatInfo->m_sMatTemplate = m_sMatTemplate;
  605.         }
  606. #endif
  607. #if defined(ENABLE_CONSOLE_MTL_VIZ)
  608.         pMatInfo->m_pConsoleMtl = m_pConsoleMtl;
  609. #endif
  610.  
  611.         if (GetShaderItem().m_pShaderResources)
  612.         {
  613.                 const SShaderItem& siSrc(GetShaderItem());
  614.                 SInputShaderResourcesPtr pIsr = GetRenderer()->EF_CreateInputShaderResource(siSrc.m_pShaderResources);
  615.                
  616.                 const SShaderItem& siDstTex(pMatInfo->GetShaderItem());
  617.                 SInputShaderResourcesPtr idsTex = GetRenderer()->EF_CreateInputShaderResource(siDstTex.m_pShaderResources);
  618.  
  619.                 if (!(flags & MTL_COPY_TEXTURES))
  620.                 {
  621.                         for (int n = 0; n < EFTT_MAX; n++)
  622.                         {
  623.                                 pIsr->m_Textures[n] = idsTex->m_Textures[n];
  624.                         }
  625.                 }
  626.  
  627.                 SShaderItem siDst(GetRenderer()->EF_LoadShaderItem(siSrc.m_pShader->GetName(), false, 0, pIsr, siSrc.m_pShader->GetGenerationMask()));
  628.                 siDst.m_pShaderResources->CloneConstants(siSrc.m_pShaderResources); // Lazy "Copy", stays a reference until changed, after which it becomes unlinked
  629.                 pMatInfo->AssignShaderItem(siDst);
  630.         }
  631. }
  632.  
  633. //////////////////////////////////////////////////////////////////////////
  634. CMatInfo* CMatInfo::Clone(CMatInfo* pParentOfClonedMtl)
  635. {
  636.         CMatInfo* pMatInfo = new CMatInfo;
  637.  
  638.         pMatInfo->m_sMaterialName = m_sMaterialName;
  639.         pMatInfo->m_sUniqueMaterialName = m_sUniqueMaterialName;
  640.         pMatInfo->m_nSurfaceTypeId = m_nSurfaceTypeId;
  641.         pMatInfo->m_Flags = m_Flags;
  642. #ifdef SUPPORT_MATERIAL_EDITING
  643.         pMatInfo->m_sMatTemplate = m_sMatTemplate;
  644. #endif
  645. #if defined(ENABLE_CONSOLE_MTL_VIZ)
  646.         pMatInfo->m_pConsoleMtl = m_pConsoleMtl;
  647. #endif
  648.  
  649.         if (GetShaderItem().m_pShaderResources)
  650.         {
  651.                 const SShaderItem& siSrc(GetShaderItem());
  652.  
  653.                 SShaderItem siDst(siSrc.Clone());
  654.                 pMatInfo->AssignShaderItem(siDst);
  655.         }
  656.  
  657.         return pMatInfo;
  658. }
  659.  
  660. //////////////////////////////////////////////////////////////////////////
  661. void CMatInfo::GetMemoryUsage(ICrySizer* pSizer) const
  662. {
  663.         SIZER_COMPONENT_NAME(pSizer, "Material");
  664.         pSizer->AddObject(this, sizeof(*this));
  665.  
  666.         if (m_pMaterialLayers)
  667.         {
  668.                 int n = m_pMaterialLayers->size();
  669.                 for (int i = 0; i < n; i++)
  670.                 {
  671.                         CMaterialLayer* pMaterialLayer = (*m_pMaterialLayers)[i];
  672.                         if (pMaterialLayer)
  673.                         {
  674.                                 pMaterialLayer->GetMemoryUsage(pSizer);
  675.                         }
  676.                 }
  677.         }
  678.  
  679.         // all sub material
  680.         {
  681.                 pSizer->AddObject(m_subMtls);
  682.         }
  683. }
  684. //////////////////////////////////////////////////////////////////////////
  685. size_t CMatInfo::GetResourceMemoryUsage(ICrySizer* pSizer)
  686. {
  687.         size_t nTotalResourceMemoryUsage(0);
  688.  
  689.         if (m_pMaterialLayers)
  690.         {
  691.                 int n = m_pMaterialLayers->size();
  692.                 for (int i = 0; i < n; i++)
  693.                 {
  694.                         CMaterialLayer* pMaterialLayer = (*m_pMaterialLayers)[i];
  695.                         if (pMaterialLayer)
  696.                         {
  697.                                 nTotalResourceMemoryUsage += pMaterialLayer->GetResourceMemoryUsage(pSizer);
  698.                         }
  699.                 }
  700.         }
  701.  
  702.         if (m_shaderItem.m_pShaderResources)
  703.         {
  704.                 nTotalResourceMemoryUsage += m_shaderItem.m_pShaderResources->GetResourceMemoryUsage(pSizer);
  705.         }
  706.  
  707.         // all sub material
  708.         {
  709.                 int iCnt = GetSubMtlCount();
  710.                 for (int i = 0; i < iCnt; ++i)
  711.                 {
  712.                         IMaterial* piMaterial(GetSubMtl(i));
  713.                         if (piMaterial)
  714.                         {
  715.                                 nTotalResourceMemoryUsage += piMaterial->GetResourceMemoryUsage(pSizer);
  716.                         }
  717.                 }
  718.         }
  719.         return nTotalResourceMemoryUsage;
  720. }
  721.  
  722. //////////////////////////////////////////////////////////////////////////
  723. bool CMatInfo::SetGetMaterialParamFloat(const char* sParamName, float& v, bool bGet)
  724. {
  725.         if (!m_shaderItem.m_pShaderResources)
  726.                 return false;
  727.  
  728.         bool bEmissive = m_shaderItem.m_pShaderResources->IsEmissive();
  729.         bool bOk = m_shaderItem.m_pShaderResources && GetMaterialHelpers().SetGetMaterialParamFloat(*m_shaderItem.m_pShaderResources, sParamName, v, bGet);
  730.         if (bOk && m_shaderItem.m_pShader && !bGet)
  731.         {
  732.                 // since "emissive_intensity" is a post effect it needs to be updated here
  733.                 if (bEmissive != m_shaderItem.m_pShaderResources->IsEmissive())
  734.                 {
  735.                         GetRenderer()->ForceUpdateShaderItem(&m_shaderItem, this);
  736.                         IncrementModificationId();
  737.                 }
  738.  
  739.                 m_shaderItem.m_pShaderResources->UpdateConstants(m_shaderItem.m_pShader);
  740.         }
  741.  
  742.         return bOk;
  743. }
  744.  
  745. bool CMatInfo::SetGetMaterialParamVec3(const char* sParamName, Vec3& v, bool bGet)
  746. {
  747.         bool bOk = m_shaderItem.m_pShaderResources && GetMaterialHelpers().SetGetMaterialParamVec3(*m_shaderItem.m_pShaderResources, sParamName, v, bGet);
  748.         if (bOk && m_shaderItem.m_pShader && !bGet)
  749.         {
  750.                 m_shaderItem.m_pShaderResources->UpdateConstants(m_shaderItem.m_pShader);
  751.         }
  752.  
  753.         return bOk;
  754. }
  755.  
  756. void CMatInfo::SetTexture(int textureId, int textureSlot)
  757. {
  758.         ITexture* pTexture = gEnv->pRenderer->EF_GetTextureByID(textureId);
  759.         if (pTexture)
  760.         {
  761.                 ITexture*& pTex = m_shaderItem.m_pShaderResources->GetTexture(textureSlot)->m_Sampler.m_pITex;
  762.                 SAFE_RELEASE(pTex);
  763.                 pTex = pTexture;
  764.         }
  765. }
  766.  
  767. void CMatInfo::SetSubTexture(int textureId, int subMaterialSlot, int textureSlot)
  768. {
  769.         ITexture* pTexture = gEnv->pRenderer->EF_GetTextureByID(textureId);
  770.         if (pTexture)
  771.         {
  772.                 if (IMaterial* pSubMtl = GetSubMtl(subMaterialSlot))
  773.                 {
  774.                         ITexture*& pTex = pSubMtl->GetShaderItem().m_pShaderResources->GetTexture(textureSlot)->m_Sampler.m_pITex;
  775.                         SAFE_RELEASE(pTex);
  776.                         pTex = pTexture;
  777.                 }
  778.         }
  779. }
  780.  
  781. //////////////////////////////////////////////////////////////////////////
  782. void CMatInfo::SetCamera(CCamera& cam)
  783. {
  784.         if (!m_shaderItem.m_pShaderResources)
  785.         {
  786.                 return;
  787.         }
  788.  
  789.         CCamera* pC = m_shaderItem.m_pShaderResources->GetCamera();
  790.         if (!pC)
  791.                 pC = new CCamera;
  792.         m_shaderItem.m_pShaderResources->SetCamera(pC);
  793. }
  794.  
  795. //////////////////////////////////////////////////////////////////////////
  796. void CMatInfo::SetSketchMode(int mode)
  797. {
  798. #ifdef SUPPORT_MATERIAL_SKETCH
  799.         if (mode == 0)
  800.         {
  801.                 if (m_pPreSketchShader)
  802.                 {
  803.                         m_shaderItem.m_pShader = m_pPreSketchShader;
  804.                         m_shaderItem.m_nTechnique = m_nPreSketchTechnique;
  805.                         m_pPreSketchShader = 0;
  806.                         m_nPreSketchTechnique = 0;
  807.                 }
  808.         }
  809.         else
  810.         {
  811.                 if (m_shaderItem.m_pShader && m_shaderItem.m_pShader != m_pPreSketchShader)
  812.                 {
  813.                         EShaderType shaderType = m_shaderItem.m_pShader->GetShaderType();
  814.  
  815.                         //      nGenerationMask = (uint32)m_shaderItem.m_pShader->GetGenerationMask();
  816.  
  817.                         // Do not replace this shader types.
  818.                         switch (shaderType)
  819.                         {
  820.                         case eST_Terrain:
  821.                         case eST_Shadow:
  822.                         case eST_Water:
  823.                         case eST_FX:
  824.                         case eST_PostProcess:
  825.                         case eST_HDR:
  826.                         case eST_Sky:
  827.                         case eST_Particle:
  828.                                 // For this shaders do not replace them.
  829.                                 return;
  830.                         case eST_Vegetation:
  831.                                 {
  832.                                         // in low spec mode also skip vegetation - we have low spec vegetation shader
  833.                                         if (mode == 3)
  834.                                                 return;
  835.                                 }
  836.                         }
  837.                 }
  838.  
  839.                 if (!m_pPreSketchShader)
  840.                 {
  841.                         m_pPreSketchShader = m_shaderItem.m_pShader;
  842.                         m_nPreSketchTechnique = m_shaderItem.m_nTechnique;
  843.                 }
  844.  
  845.                 //m_shaderItem.m_pShader = ((CMatMan*)GetMatMan())->GetDefaultHelperMaterial()->GetShaderItem().m_pShader;
  846.                 if (mode == 1)
  847.                 {
  848.                         m_shaderItem.m_pShader = gEnv->pRenderer->EF_LoadShader("Sketch");
  849.                         m_shaderItem.m_nTechnique = 0;
  850.                 }
  851.                 else if (mode == 2)
  852.                 {
  853.                         m_shaderItem.m_pShader = gEnv->pRenderer->EF_LoadShader("Sketch.Fast");
  854.                         m_shaderItem.m_nTechnique = 0;
  855.                 }
  856.                 else if (mode == 4)
  857.                 {
  858.                         SShaderItem tmp = gEnv->pRenderer->EF_LoadShaderItem("Sketch.TexelsPerMeter", false);
  859.                         m_shaderItem.m_pShader = tmp.m_pShader;
  860.                         m_shaderItem.m_nTechnique = tmp.m_nTechnique;
  861.                 }
  862.  
  863.                 if (m_shaderItem.m_pShader)
  864.                         m_shaderItem.m_pShader->AddRef();
  865.         }
  866.         for (int i = 0; i < (int)m_subMtls.size(); i++)
  867.         {
  868.                 if (m_subMtls[i])
  869.                 {
  870.                         m_subMtls[i]->SetSketchMode(mode);
  871.                 }
  872.         }
  873. #endif
  874. }
  875.  
  876. void CMatInfo::SetTexelDensityDebug(int mode)
  877. {
  878. #ifdef SUPPORT_MATERIAL_SKETCH
  879.         if (m_shaderItem.m_pShader)
  880.         {
  881.                 EShaderType shaderType = m_pPreSketchShader ? m_pPreSketchShader->GetShaderType() : m_shaderItem.m_pShader->GetShaderType();
  882.  
  883.                 switch (shaderType)
  884.                 {
  885.                 case eST_Terrain:
  886.                         if (mode == 3 || mode == 4)
  887.                         {
  888.                                 if (m_nSurfaceTypeId == 0)
  889.                                 {
  890.                                         mode = 0;
  891.                                 }
  892.  
  893.                                 break;
  894.                         }
  895.                 case eST_Shadow:
  896.                 case eST_Water:
  897.                 case eST_FX:
  898.                 case eST_PostProcess:
  899.                 case eST_HDR:
  900.                 case eST_Sky:
  901.                 case eST_Particle:
  902.                         // For this shaders do not replace them.
  903.                         mode = 0;
  904.                         break;
  905.                 default:
  906.                         if (mode == 1 || mode == 2)
  907.                         {
  908.                                 break;
  909.                         }
  910.                         mode = 0;
  911.                         break;
  912.                 }
  913.  
  914.                 if (mode == 0)
  915.                 {
  916.                         if (m_pPreSketchShader)
  917.                         {
  918.                                 m_shaderItem.m_pShader = m_pPreSketchShader;
  919.                                 m_shaderItem.m_nTechnique = m_nPreSketchTechnique;
  920.                                 m_pPreSketchShader = 0;
  921.                                 m_nPreSketchTechnique = 0;
  922.                         }
  923.                 }
  924.                 else
  925.                 {
  926.                         if (!m_pPreSketchShader)
  927.                         {
  928.                                 m_pPreSketchShader = m_shaderItem.m_pShader;
  929.                                 m_nPreSketchTechnique = m_shaderItem.m_nTechnique;
  930.                         }
  931.  
  932.                         SShaderItem tmp;
  933.                         if (mode == 3 || mode == 4)
  934.                         {
  935.                                 tmp = gEnv->pRenderer->EF_LoadShaderItem("SketchTerrain.TexelDensityTerrainLayer", false);
  936.                         }
  937.                         else
  938.                         {
  939.                                 tmp = gEnv->pRenderer->EF_LoadShaderItem("Sketch.TexelDensity", false);
  940.                         }
  941.                         m_shaderItem.m_pShader = tmp.m_pShader;
  942.                         m_shaderItem.m_nTechnique = tmp.m_nTechnique;
  943.                 }
  944.         }
  945.  
  946.         for (int i = 0; i < (int)m_subMtls.size(); i++)
  947.         {
  948.                 if (m_subMtls[i])
  949.                 {
  950.                         m_subMtls[i]->SetTexelDensityDebug(mode);
  951.                 }
  952.         }
  953. #endif
  954. }
  955.  
  956. const char* CMatInfo::GetLoadingCallstack()
  957. {
  958. #ifdef TRACE_MATERIAL_LEAKS
  959.         return m_sLoadingCallstack.c_str();
  960. #else
  961.         return "";
  962. #endif
  963. }
  964.  
  965. void CMatInfo::PrecacheMaterial(const float _fEntDistance, IRenderMesh* pRenderMesh, bool bFullUpdate, bool bDrawNear)
  966. {
  967.         //      FUNCTION_PROFILER_3DENGINE;
  968.         LOADING_TIME_PROFILE_SECTION;
  969.  
  970.         int nFlags = 0;
  971.         float fEntDistance;
  972.         if (bDrawNear)
  973.         {
  974.                 fEntDistance = _fEntDistance;
  975.                 nFlags |= FPR_HIGHPRIORITY;
  976.         }
  977.         else
  978.                 fEntDistance = max(GetFloatCVar(e_StreamPredictionMinReportDistance), _fEntDistance);
  979.  
  980.         float fMipFactor = fEntDistance * fEntDistance;
  981.  
  982.         // updating texture streaming distances
  983.         if (pRenderMesh)
  984.         {
  985.                 TRenderChunkArray* pChunks = &pRenderMesh->GetChunks();
  986.  
  987.                 if (pChunks != NULL)
  988.                 {
  989.                         for (uint32 i = 0, size = pChunks->size(); i < size; i++)
  990.                         {
  991.                                 PrecacheChunkTextures(fMipFactor, nFlags, &(*pChunks)[i], bFullUpdate);
  992.                         }
  993.                 }
  994.  
  995.                 pChunks = &pRenderMesh->GetChunksSkinned();
  996.                 for (uint32 i = 0, size = pChunks->size(); i < size; i++)
  997.                 {
  998.                         PrecacheChunkTextures(fMipFactor, nFlags, &(*pChunks)[i], bFullUpdate);
  999.                 }
  1000.         }
  1001.         else
  1002.         {
  1003.                 PrecacheChunkTextures(fMipFactor, nFlags, NULL, bFullUpdate);
  1004.         }
  1005. }
  1006.  
  1007. void CMatInfo::RequestTexturesLoading(const float fMipFactor)
  1008. {
  1009.         PrecacheTextures(fMipFactor, FPR_STARTLOADING, false);
  1010. }
  1011.  
  1012. void CMatInfo::ForceTexturesLoading(const float fMipFactor)
  1013. {
  1014.         PrecacheTextures(fMipFactor, FPR_STARTLOADING + FPR_HIGHPRIORITY, true);
  1015. }
  1016.  
  1017. void CMatInfo::ForceTexturesLoading(const int iScreenTexels)
  1018. {
  1019.         PrecacheTextures(iScreenTexels, FPR_STARTLOADING + FPR_HIGHPRIORITY, true);
  1020. }
  1021.  
  1022. void CMatInfo::PrecacheTextures(const float fMipFactor, const int nFlags, bool bFullUpdate)
  1023. {
  1024.         SStreamingPredictionZone& rZone = m_streamZoneInfo[bFullUpdate ? 1 : 0];
  1025.         int bHighPriority = (nFlags & FPR_HIGHPRIORITY) != 0;
  1026.  
  1027.         rZone.fMinMipFactor = min(rZone.fMinMipFactor, fMipFactor);
  1028.         rZone.bHighPriority |= bHighPriority;
  1029.  
  1030.         int nRoundId = bFullUpdate ? GetObjManager()->m_nUpdateStreamingPrioriryRoundIdFast : GetObjManager()->m_nUpdateStreamingPrioriryRoundId;
  1031.  
  1032.         // TODO: fix fast update
  1033.         if (rZone.nRoundId != nRoundId)
  1034.         {
  1035.                 int nCurrentFlags = Get3DEngine()->IsShadersSyncLoad() ? FPR_SYNCRONOUS : 0;
  1036.                 nCurrentFlags |= bFullUpdate ? FPR_SINGLE_FRAME_PRIORITY_UPDATE : 0;
  1037.  
  1038.                 SShaderItem& rSI = m_shaderItem;
  1039.                 if (rSI.m_pShader && rSI.m_pShaderResources && !(rSI.m_pShader->GetFlags() & EF_NODRAW))
  1040.                 {
  1041.                         if (rZone.nRoundId == (nRoundId - 1))
  1042.                         {
  1043.                                 nCurrentFlags |= rZone.bHighPriority ? FPR_HIGHPRIORITY : 0;
  1044.                                 GetRenderer()->EF_PrecacheResource(&rSI, rZone.fMinMipFactor, 0, nCurrentFlags, nRoundId, 1); // accumulated value is valid
  1045.                         }
  1046.                         else
  1047.                         {
  1048.                                 nCurrentFlags |= (nFlags & FPR_HIGHPRIORITY);
  1049.                                 GetRenderer()->EF_PrecacheResource(&rSI, fMipFactor, 0, nCurrentFlags, nRoundId, 1); // accumulated value is not valid, pass current value
  1050.                         }
  1051.                 }
  1052.  
  1053.                 rZone.nRoundId = nRoundId;
  1054.                 rZone.fMinMipFactor = fMipFactor;
  1055.                 rZone.bHighPriority = bHighPriority;
  1056.         }
  1057. }
  1058.  
  1059. void CMatInfo::PrecacheTextures(const int iScreenTexels, const int nFlags, bool bFullUpdate)
  1060. {
  1061.         int nRoundId = bFullUpdate ? GetObjManager()->m_nUpdateStreamingPrioriryRoundIdFast : GetObjManager()->m_nUpdateStreamingPrioriryRoundId;
  1062.  
  1063.         // TODO: fix fast update
  1064.         if (true)
  1065.         {
  1066.                 int nCurrentFlags = Get3DEngine()->IsShadersSyncLoad() ? FPR_SYNCRONOUS : 0;
  1067.                 nCurrentFlags |= bFullUpdate ? FPR_SINGLE_FRAME_PRIORITY_UPDATE : 0;
  1068.  
  1069.                 SShaderItem& rSI = m_shaderItem;
  1070.                 if (rSI.m_pShader && rSI.m_pShaderResources && !(rSI.m_pShader->GetFlags() & EF_NODRAW))
  1071.                 {
  1072.                         {
  1073.                                 nCurrentFlags |= (nFlags & FPR_HIGHPRIORITY);
  1074.                                 GetRenderer()->EF_PrecacheResource(&rSI, iScreenTexels, 0, nCurrentFlags, nRoundId, 1); // accumulated value is not valid, pass current value
  1075.                         }
  1076.                 }
  1077.         }
  1078. }
  1079.  
  1080. void CMatInfo::PrecacheChunkTextures(const float fMipFactorDef, const int nFlags, CRenderChunk* pRenderChunk, bool bFullUpdate)
  1081. {
  1082.         //  FUNCTION_PROFILER_3DENGINE;
  1083.  
  1084.         CMatInfo* pMaterial = this;
  1085.  
  1086.         if (pRenderChunk && pRenderChunk->pRE && pRenderChunk->nNumIndices && pRenderChunk->nNumVerts)
  1087.         {
  1088.                 // chunk is defined and have valid geometry
  1089.                 if (pRenderChunk->m_nMatID < (uint16)m_subMtls.size())
  1090.                 {
  1091.                         pMaterial = (CMatInfo*)m_subMtls[pRenderChunk->m_nMatID];
  1092.                 }
  1093.  
  1094.                 if (pMaterial != NULL)
  1095.                 {
  1096.                         float fMipFactor = GetCVars()->e_StreamPredictionTexelDensity ? (fMipFactorDef * pRenderChunk->m_texelAreaDensity) : fMipFactorDef;
  1097.                         pMaterial->PrecacheTextures(fMipFactor, nFlags, bFullUpdate);
  1098.                 }
  1099.         }
  1100.         else if (!pRenderChunk)
  1101.         {
  1102.                 // chunk is not set - load all sub-materials
  1103.                 float fMipFactor = fMipFactorDef;
  1104.  
  1105.                 PrecacheTextures(fMipFactor, nFlags, bFullUpdate);
  1106.  
  1107.                 for (int nSubMtl = 0; nSubMtl < (int)m_subMtls.size(); ++nSubMtl)
  1108.                 {
  1109.                         pMaterial = m_subMtls[nSubMtl];
  1110.  
  1111.                         if (pMaterial != NULL)
  1112.                         {
  1113.                                 pMaterial->PrecacheTextures(fMipFactor, nFlags, bFullUpdate);
  1114.                         }
  1115.                 }
  1116.         }
  1117. }
  1118.  
  1119. //////////////////////////////////////////////////////////////////////////
  1120. int CMatInfo::GetTextureMemoryUsage(ICrySizer* pSizer, int nSubMtlSlot)
  1121. {
  1122.         int textureSize = 0;
  1123.         std::set<ITexture*> used;
  1124.  
  1125.         int nSlotStart = 0;
  1126.         int nSlotEnd = (int)m_subMtls.size();
  1127.  
  1128.         if (nSubMtlSlot >= 0)
  1129.         {
  1130.                 nSlotStart = nSubMtlSlot;
  1131.                 nSlotEnd = nSubMtlSlot + 1;
  1132.         }
  1133.         if (nSlotEnd >= (int)m_subMtls.size())
  1134.                 nSlotEnd = (int)m_subMtls.size();
  1135.  
  1136.         if (nSlotEnd == 0)
  1137.                 nSlotEnd = 1;
  1138.  
  1139.         for (int i = nSlotStart; i < nSlotEnd; i++)
  1140.         {
  1141.                 IRenderShaderResources* pRes = m_shaderItem.m_pShaderResources;
  1142.                 if (i < (int)m_subMtls.size() && m_subMtls[i] != NULL && (m_Flags & MTL_FLAG_MULTI_SUBMTL))
  1143.                 {
  1144.                         SShaderItem shaderItem = m_subMtls[i]->m_shaderItem;
  1145.                         if (!shaderItem.m_pShaderResources)
  1146.                                 continue;
  1147.                         pRes = shaderItem.m_pShaderResources;
  1148.                 }
  1149.                 if (!pRes)
  1150.                         continue;
  1151.  
  1152.                 for (int j = 0; j < EFTT_MAX; j++)
  1153.                 {
  1154.                         SEfResTexture* pResTexure = pRes->GetTexture(j);
  1155.                         if (!pResTexure || !pResTexure->m_Sampler.m_pITex)
  1156.                                 continue;
  1157.  
  1158.                         ITexture* pTexture = pResTexure->m_Sampler.m_pITex;
  1159.                         if (!pTexture)
  1160.                                 continue;
  1161.  
  1162.                         if (used.find(pTexture) != used.end()) // Already used in size calculation.
  1163.                                 continue;
  1164.                         used.insert(pTexture);
  1165.  
  1166.                         int nTexSize = pTexture->GetDataSize();
  1167.                         textureSize += nTexSize;
  1168.  
  1169.                         if (pSizer)
  1170.                                 pSizer->AddObject(pTexture, nTexSize);
  1171.                 }
  1172.         }
  1173.  
  1174.         return textureSize;
  1175. }
  1176.  
  1177. void CMatInfo::SetKeepLowResSysCopyForDiffTex()
  1178. {
  1179.         int nSlotStart = 0;
  1180.         int nSlotEnd = (int)m_subMtls.size();
  1181.  
  1182.         if (nSlotEnd == 0)
  1183.                 nSlotEnd = 1;
  1184.  
  1185.         for (int i = nSlotStart; i < nSlotEnd; i++)
  1186.         {
  1187.                 IRenderShaderResources* pRes = m_shaderItem.m_pShaderResources;
  1188.  
  1189.                 if (i < (int)m_subMtls.size() && m_subMtls[i] != NULL && (m_Flags & MTL_FLAG_MULTI_SUBMTL))
  1190.                 {
  1191.                         SShaderItem shaderItem = m_subMtls[i]->m_shaderItem;
  1192.                         if (!shaderItem.m_pShaderResources)
  1193.                                 continue;
  1194.                         pRes = shaderItem.m_pShaderResources;
  1195.                 }
  1196.  
  1197.                 if (!pRes)
  1198.                         continue;
  1199.  
  1200. #ifndef FEATURE_SVO_GI_ALLOW_HQ
  1201.                 // For non HQ mode (consoles) keep the texture only if material is going to use alpha value from it
  1202.                 if ((pRes->GetAlphaRef() == 0.f) && (pRes->GetStrengthValue(EFTT_OPACITY) == 1.f))
  1203.                         continue;
  1204. #endif
  1205.                
  1206.                 int j = EFTT_DIFFUSE;
  1207.                 {
  1208.                         SEfResTexture* pResTexure = pRes->GetTexture(j);
  1209.                         if (!pResTexure || !pResTexure->m_Sampler.m_pITex)
  1210.                                 continue;
  1211.                         ITexture* pTexture = pResTexure->m_Sampler.m_pITex;
  1212.                         if (!pTexture)
  1213.                                 continue;
  1214.  
  1215.                         pTexture->SetKeepSystemCopy(true);
  1216.                 }
  1217.         }
  1218. }
  1219.  
  1220. //////////////////////////////////////////////////////////////////////////
  1221. void CMatInfo::SetMaterialLinkName(const char* name)
  1222. {
  1223. #ifdef SUPPORT_MATERIAL_EDITING
  1224.         if (name)
  1225.         {
  1226.                 m_sMaterialLinkName = name;
  1227.         }
  1228.         else
  1229.         {
  1230.                 m_sMaterialLinkName.clear();
  1231.         }
  1232. #endif
  1233. }
  1234.  
  1235. //////////////////////////////////////////////////////////////////////////
  1236. const char* CMatInfo::GetMaterialLinkName() const
  1237. {
  1238. #ifdef SUPPORT_MATERIAL_EDITING
  1239.         return m_sMaterialLinkName.c_str();
  1240. #else
  1241.         CryFatalError("CMatInfo::GetMaterialLinkName not supported on this platform");
  1242.         return "";
  1243. #endif
  1244. }
  1245.  
  1246. //////////////////////////////////////////////////////////////////////////
  1247. void CMatInfo::ActivateDynamicTextureSources(bool activate)
  1248. {
  1249.         const int numSubMtls = max(GetSubMtlCount(), 1);
  1250.         for (int subMtlId = 0; subMtlId < numSubMtls; ++subMtlId)
  1251.         {
  1252.                 IMaterial* pSubMtl = GetSafeSubMtl(subMtlId);
  1253.                 if (pSubMtl)
  1254.                 {
  1255.                         const SShaderItem& shaderItem = pSubMtl->GetShaderItem();
  1256.                         if (shaderItem.m_pShaderResources)
  1257.                         {
  1258.                                 for (int texSlot = 0; texSlot < EFTT_MAX; ++texSlot)
  1259.                                 {
  1260.                                         SEfResTexture* pTex = shaderItem.m_pShaderResources->GetTexture(texSlot);
  1261.                                         if (pTex)
  1262.                                         {
  1263.                                                 IDynTextureSource* pDynTexSrc = pTex->m_Sampler.m_pDynTexSource;
  1264.                                                 if (pDynTexSrc)
  1265.                                                 {
  1266.                                                         pDynTexSrc->Activate(activate);
  1267.                                                 }
  1268.                                         }
  1269.                                 }
  1270.                         }
  1271.                 }
  1272.         }
  1273. }
  1274.  
  1275. //////////////////////////////////////////////////////////////////////////
  1276. CryCriticalSection& CMatInfo::GetSubMaterialResizeLock()
  1277. {
  1278.         static CryCriticalSection s_sSubMaterialResizeLock;
  1279.         return s_sSubMaterialResizeLock;
  1280. }
  1281.  
  1282. //////////////////////////////////////////////////////////////////////////
  1283. void CMatInfo::UpdateShaderItems()
  1284. {
  1285.         IRenderer* pRenderer = gEnv->pRenderer;
  1286.         pRenderer->UpdateShaderItem(&m_shaderItem, this);
  1287.  
  1288.         for (int i = 0; i < (int)m_subMtls.size(); ++i)
  1289.         {
  1290.                 CMatInfo* pSubMaterial = m_subMtls[i];
  1291.                 if (pSubMaterial)
  1292.                         pRenderer->UpdateShaderItem(&pSubMaterial->m_shaderItem, this);
  1293.         }
  1294. }
  1295.  
  1296. void CMatInfo::RefreshShaderResourceConstants()
  1297. {
  1298.         IRenderer* pRenderer = gEnv->pRenderer;
  1299.         if (!pRenderer)
  1300.                 return;
  1301.  
  1302.         pRenderer->RefreshShaderResourceConstants(&m_shaderItem, this);
  1303.  
  1304.         for (int i = 0; i < (int)m_subMtls.size(); ++i)
  1305.         {
  1306.                 CMatInfo* pSubMaterial = m_subMtls[i];
  1307.                 if (pSubMaterial)
  1308.                         pRenderer->RefreshShaderResourceConstants(&pSubMaterial->m_shaderItem, this);
  1309.         }
  1310. }
  1311.  
  1312. #if CRY_PLATFORM_WINDOWS
  1313. void CMatInfo::LoadConsoleMaterial()
  1314. {
  1315.         #if defined(ENABLE_CONSOLE_MTL_VIZ)
  1316.         string conMtlName = m_sMaterialName + "_con.mtl";
  1317.         if (gEnv->pCryPak->FGetSize(conMtlName.c_str(), true))
  1318.         {
  1319.                 conMtlName.resize(conMtlName.size() - 4);
  1320.                 m_pConsoleMtl = Get3DEngine()->GetMatMan()->LoadMaterial(conMtlName.c_str(), false, false, IMaterialManager::ELoadingFlagsPreviewMode);
  1321.         }
  1322.         #endif
  1323. }
  1324. #endif
  1325.  
  1326. #if defined(ENABLE_CONSOLE_MTL_VIZ)
  1327. int CMatInfo::ms_useConsoleMat = -1;
  1328.  
  1329. void CMatInfo::RegisterConsoleMatCVar()
  1330. {
  1331.         const int defVal = gEnv->IsEditor() ? 0 : -1;
  1332.         REGISTER_CVAR2("e_UseConsoleMtl", &ms_useConsoleMat, defVal, VF_NULL,
  1333.                        "Console material visualization mode. Enable before level loading to be in effect.\n"
  1334.                        "-1 = fully disabled (default)\n"
  1335.                        " 0 = enabled but renders regular materials only\n"
  1336.                        " 1 = enabled and renders console materials where available");
  1337. }
  1338. #endif
  1339.  
  1340. ///////////////////////////////////////////////////////////////////////////////
  1341. IMaterial* CMatMan::GetDefaultMaterial()
  1342. {
  1343.         return m_pDefaultMtl;
  1344. }
  1345.  
  1346. ///////////////////////////////////////////////////////////////////////////////
  1347. IMaterial* CMatInfo::GetSafeSubMtl(int nSubMtlSlot)
  1348. {
  1349.         if (m_subMtls.empty() || !(m_Flags & MTL_FLAG_MULTI_SUBMTL))
  1350.         {
  1351.                 return this; // Not Multi material.
  1352.         }
  1353.         if (nSubMtlSlot >= 0 && nSubMtlSlot < (int)m_subMtls.size() && m_subMtls[nSubMtlSlot] != NULL)
  1354.                 return m_subMtls[nSubMtlSlot];
  1355.         else
  1356.                 return GetMatMan()->GetDefaultMaterial();
  1357. }
  1358.  
  1359. ///////////////////////////////////////////////////////////////////////////////
  1360. SShaderItem& CMatInfo::GetShaderItem()
  1361. {
  1362. #if defined(ENABLE_CONSOLE_MTL_VIZ)
  1363.         if (ms_useConsoleMat == 1 && m_pConsoleMtl)
  1364.         {
  1365.                 IMaterial* pConsoleMaterial = m_pConsoleMtl.get();
  1366.                 return static_cast<CMatInfo*>(pConsoleMaterial)->CMatInfo::GetShaderItem();
  1367.         }
  1368. #endif
  1369.  
  1370.         return m_shaderItem;
  1371. }
  1372.  
  1373. ///////////////////////////////////////////////////////////////////////////////
  1374. const SShaderItem& CMatInfo::GetShaderItem() const
  1375. {
  1376. #if defined(ENABLE_CONSOLE_MTL_VIZ)
  1377.         if (ms_useConsoleMat == 1 && m_pConsoleMtl)
  1378.         {
  1379.                 IMaterial* pConsoleMaterial = m_pConsoleMtl.get();
  1380.                 return static_cast<CMatInfo*>(pConsoleMaterial)->CMatInfo::GetShaderItem();
  1381.         }
  1382. #endif
  1383.  
  1384.         return m_shaderItem;
  1385. }
  1386.  
  1387. //////////////////////////////////////////////////////////////////////////
  1388. SShaderItem& CMatInfo::GetShaderItem(int nSubMtlSlot)
  1389. {
  1390. #if defined(ENABLE_CONSOLE_MTL_VIZ)
  1391.         if (ms_useConsoleMat == 1 && m_pConsoleMtl)
  1392.         {
  1393.                 IMaterial* pConsoleMaterial = m_pConsoleMtl.get();
  1394.                 return static_cast<CMatInfo*>(pConsoleMaterial)->CMatInfo::GetShaderItem(nSubMtlSlot);
  1395.         }
  1396. #endif
  1397.  
  1398.         SShaderItem* pShaderItem = NULL;
  1399.         if (m_subMtls.empty() || !(m_Flags & MTL_FLAG_MULTI_SUBMTL))
  1400.         {
  1401.                 pShaderItem = &m_shaderItem; // Not Multi material.
  1402.         }
  1403.         else if (nSubMtlSlot >= 0 && nSubMtlSlot < (int)m_subMtls.size() && m_subMtls[nSubMtlSlot] != NULL)
  1404.         {
  1405.                 pShaderItem = &(m_subMtls[nSubMtlSlot]->m_shaderItem);
  1406.         }
  1407.         else
  1408.         {
  1409.                 IMaterial* pDefaultMaterial = GetMatMan()->GetDefaultMaterial();
  1410.                 pShaderItem = &(static_cast<CMatInfo*>(pDefaultMaterial)->m_shaderItem);
  1411.         }
  1412.  
  1413.         return *pShaderItem;
  1414. }
  1415.  
  1416. ///////////////////////////////////////////////////////////////////////////////
  1417. const SShaderItem& CMatInfo::GetShaderItem(int nSubMtlSlot) const
  1418. {
  1419. #if defined(ENABLE_CONSOLE_MTL_VIZ)
  1420.         if (ms_useConsoleMat == 1 && m_pConsoleMtl)
  1421.         {
  1422.                 IMaterial* pConsoleMaterial = m_pConsoleMtl.get();
  1423.                 return static_cast<CMatInfo*>(pConsoleMaterial)->CMatInfo::GetShaderItem(nSubMtlSlot);
  1424.         }
  1425. #endif
  1426.  
  1427.         const SShaderItem* pShaderItem = NULL;
  1428.         if (m_subMtls.empty() || !(m_Flags & MTL_FLAG_MULTI_SUBMTL))
  1429.         {
  1430.                 pShaderItem = &m_shaderItem; // Not Multi material.
  1431.         }
  1432.         else if (nSubMtlSlot >= 0 && nSubMtlSlot < (int)m_subMtls.size() && m_subMtls[nSubMtlSlot] != NULL)
  1433.         {
  1434.                 pShaderItem = &(m_subMtls[nSubMtlSlot]->m_shaderItem);
  1435.         }
  1436.         else
  1437.         {
  1438.                 IMaterial* pDefaultMaterial = GetMatMan()->GetDefaultMaterial();
  1439.                 pShaderItem = &(static_cast<CMatInfo*>(pDefaultMaterial)->m_shaderItem);
  1440.         }
  1441.  
  1442.         return *pShaderItem;
  1443. }
  1444.  
  1445. ///////////////////////////////////////////////////////////////////////////////
  1446. bool CMatInfo::IsForwardRenderingRequired()
  1447. {
  1448.         bool bRequireForwardRendering = (m_Flags & MTL_FLAG_REQUIRE_FORWARD_RENDERING) != 0;
  1449.  
  1450.         if (!bRequireForwardRendering)
  1451.         {
  1452.                 for (int i = 0; i < (int)m_subMtls.size(); ++i)
  1453.                 {
  1454.                         if (m_subMtls[i] != 0 && m_subMtls[i]->m_Flags & MTL_FLAG_REQUIRE_FORWARD_RENDERING)
  1455.                         {
  1456.                                 bRequireForwardRendering = true;
  1457.                                 break;
  1458.                         }
  1459.                 }
  1460.         }
  1461.  
  1462.         return bRequireForwardRendering;
  1463. }
  1464.  
  1465. ///////////////////////////////////////////////////////////////////////////////
  1466. bool CMatInfo::IsNearestCubemapRequired()
  1467. {
  1468.         bool bRequireNearestCubemap = (m_Flags & MTL_FLAG_REQUIRE_NEAREST_CUBEMAP) != 0;
  1469.  
  1470.         if (!bRequireNearestCubemap)
  1471.         {
  1472.                 for (int i = 0; i < (int)m_subMtls.size(); ++i)
  1473.                 {
  1474.                         if (m_subMtls[i] != 0 && m_subMtls[i]->m_Flags & MTL_FLAG_REQUIRE_NEAREST_CUBEMAP)
  1475.                         {
  1476.                                 bRequireNearestCubemap = true;
  1477.                                 break;
  1478.                         }
  1479.                 }
  1480.         }
  1481.  
  1482.         return bRequireNearestCubemap;
  1483. }
  1484.  
  1485. ///////////////////////////////////////////////////////////////////////////////
  1486. ///////////////////////////////////////////////////////////////////////////////
  1487.  
downloadMaterial.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top