#pragma once template class Material: public BaseMaterial { public: Material(const std::wstring& effectFile) { if(!m_EffectInstanceLoaded) m_EffectFile = effectFile; ++m_References; } ~Material() override { --m_References; if(m_References <= 0) { m_VariableIndexLUT.clear(); for(auto& pair:m_Techniques) { //SafeRelease(pair.second.pTechnique); SafeRelease(pair.second.pInputLayout); pair.second.inputLayoutID = 0; pair.second.inputLayoutSize = 0; pair.second.pInputLayoutDescriptions.clear(); } m_Techniques.clear(); m_EffectInstanceLoaded = false; } } Material(const Material& other) = delete; Material(Material&& other) noexcept = delete; Material& operator=(const Material& other) = delete; Material& operator=(Material&& other) noexcept = delete; void Initialize(const D3D11Context& d3d11Context, UINT materialId) override { if (!m_EffectInstanceLoaded) { //Load Effect m_pRootEffect = ContentManager::Load(m_EffectFile); //EFFECT VARIABLES //(Load) D3DX11_EFFECT_DESC effectDesc{}; m_pRootEffect->GetDesc(&effectDesc); m_VariableIndexLUT.clear(); std::fill_n(m_RootVariableIndexLUT, static_cast(eRootVariable::COUNT), -1); for (UINT i{ 0 }; i < effectDesc.GlobalVariables; ++i) { const auto pVariable = m_pRootEffect->GetVariableByIndex(i); D3DX11_EFFECT_VARIABLE_DESC variableDesc{}; pVariable->GetDesc(&variableDesc); auto variableHash = std::hash < std::wstring >{}(StringUtil::utf8_decode(variableDesc.Name)); m_VariableIndexLUT.insert(std::make_pair(variableHash, i)); //Search Root Variable //Check for Semantic >> Possible Root Variable if (variableDesc.Semantic == nullptr) continue; auto semanticStr = std::string(variableDesc.Semantic); std::ranges::transform(semanticStr, semanticStr.begin(), ::tolower); if(m_RootVariableSemanticLUT.contains(semanticStr)) { m_RootVariableIndexLUT[static_cast(m_RootVariableSemanticLUT[semanticStr])] = i; } } //TECHNIQUES //(Load) m_numTechniques = effectDesc.Techniques; m_Techniques.clear(); for (UINT i{ 0 }; i < m_numTechniques; ++i) { const auto pTechnique = m_pRootEffect->GetTechniqueByIndex(i); D3DX11_TECHNIQUE_DESC techDesc{}; pTechnique->GetDesc(&techDesc); //Create Technique Context MaterialTechniqueContext techCtx{}; techCtx.pTechnique = pTechnique; EffectHelper::BuildInputLayout(d3d11Context.pDevice, pTechnique, &techCtx.pInputLayout, techCtx.pInputLayoutDescriptions, techCtx.inputLayoutSize, techCtx.inputLayoutID); //Add to map auto techniqueHash = std::hash < std::wstring >{}(StringUtil::utf8_decode(techDesc.Name)); m_Techniques.insert(std::make_pair(techniqueHash, techCtx)); } m_EffectInstanceLoaded = true; } _baseInitialize(m_pRootEffect, materialId); SetTechnique(0); InitializeEffectVariables(); } protected: const std::map& GetVariableIndexLUT() const override { return m_VariableIndexLUT; } int GetRootVariableIndex(eRootVariable rootVariable) const override { return m_RootVariableIndexLUT[static_cast(rootVariable)]; } const std::map& GetTechniques() const override { return m_Techniques; } const std::wstring& GetEffectName() const override { return m_EffectFile; } private: static int m_References; static bool m_EffectInstanceLoaded; static std::map m_VariableIndexLUT; static std::map m_Techniques; static int m_RootVariableIndexLUT[]; static ID3DX11Effect* m_pRootEffect; static std::wstring m_EffectFile; }; template bool Material::m_EffectInstanceLoaded{}; template int Material::m_References{0}; template std::wstring Material::m_EffectFile{}; template ID3DX11Effect* Material::m_pRootEffect{}; template std::map Material::m_VariableIndexLUT{}; template int Material::m_RootVariableIndexLUT[static_cast(eRootVariable::COUNT)]{}; template std::map Material::m_Techniques{};