in Src/EffectFactory.cpp [115:367]
std::shared_ptr<IEffect> EffectFactory::Impl::CreateEffect(IEffectFactory* factory, const IEffectFactory::EffectInfo& info, ID3D11DeviceContext* deviceContext)
{
if (info.enableSkinning)
{
if (info.enableNormalMaps && mUseNormalMapEffect)
{
// SkinnedNormalMapEffect
if (mSharing && info.name && *info.name)
{
auto it = mEffectNormalMapSkinned.find(info.name);
if (mSharing && it != mEffectNormalMapSkinned.end())
{
return it->second;
}
}
auto effect = std::make_shared<SkinnedNormalMapEffect>(mDevice.Get());
SetMaterialProperties(effect.get(), info);
if (info.diffuseTexture && *info.diffuseTexture)
{
ComPtr<ID3D11ShaderResourceView> srv;
factory->CreateTexture(info.diffuseTexture, deviceContext, srv.GetAddressOf());
effect->SetTexture(srv.Get());
}
if (info.specularTexture && *info.specularTexture)
{
ComPtr<ID3D11ShaderResourceView> srv;
factory->CreateTexture(info.specularTexture, deviceContext, srv.GetAddressOf());
effect->SetSpecularTexture(srv.Get());
}
if (info.normalTexture && *info.normalTexture)
{
ComPtr<ID3D11ShaderResourceView> srv;
factory->CreateTexture(info.normalTexture, deviceContext, srv.GetAddressOf());
effect->SetNormalTexture(srv.Get());
}
if (mSharing && info.name && *info.name)
{
std::lock_guard<std::mutex> lock(mutex);
EffectCache::value_type v(info.name, effect);
mEffectNormalMapSkinned.insert(v);
}
return std::move(effect);
}
else
{
// SkinnedEffect
if (mSharing && info.name && *info.name)
{
auto it = mEffectCacheSkinning.find(info.name);
if (mSharing && it != mEffectCacheSkinning.end())
{
return it->second;
}
}
auto effect = std::make_shared<SkinnedEffect>(mDevice.Get());
SetMaterialProperties(effect.get(), info);
if (info.diffuseTexture && *info.diffuseTexture)
{
ComPtr<ID3D11ShaderResourceView> srv;
factory->CreateTexture(info.diffuseTexture, deviceContext, srv.GetAddressOf());
effect->SetTexture(srv.Get());
}
if (mSharing && info.name && *info.name)
{
std::lock_guard<std::mutex> lock(mutex);
EffectCache::value_type v(info.name, effect);
mEffectCacheSkinning.insert(v);
}
return std::move(effect);
}
}
else if (info.enableDualTexture)
{
// DualTextureEffect
if (mSharing && info.name && *info.name)
{
auto it = mEffectCacheDualTexture.find(info.name);
if (mSharing && it != mEffectCacheDualTexture.end())
{
return it->second;
}
}
auto effect = std::make_shared<DualTextureEffect>(mDevice.Get());
// Dual texture effect doesn't support lighting (usually it's lightmaps)
effect->SetAlpha(info.alpha);
if (info.perVertexColor)
{
effect->SetVertexColorEnabled(true);
}
XMVECTOR color = XMLoadFloat3(&info.diffuseColor);
effect->SetDiffuseColor(color);
if (info.diffuseTexture && *info.diffuseTexture)
{
ComPtr<ID3D11ShaderResourceView> srv;
factory->CreateTexture(info.diffuseTexture, deviceContext, srv.GetAddressOf());
effect->SetTexture(srv.Get());
}
if (info.emissiveTexture && *info.emissiveTexture)
{
ComPtr<ID3D11ShaderResourceView> srv;
factory->CreateTexture(info.emissiveTexture, deviceContext, srv.GetAddressOf());
effect->SetTexture2(srv.Get());
}
else if (info.specularTexture && *info.specularTexture)
{
// If there's no emissive texture specified, use the specular texture as the second texture
ComPtr<ID3D11ShaderResourceView> srv;
factory->CreateTexture(info.specularTexture, deviceContext, srv.GetAddressOf());
effect->SetTexture2(srv.Get());
}
if (mSharing && info.name && *info.name)
{
std::lock_guard<std::mutex> lock(mutex);
EffectCache::value_type v(info.name, effect);
mEffectCacheDualTexture.insert(v);
}
return std::move(effect);
}
else if (info.enableNormalMaps && mUseNormalMapEffect)
{
// NormalMapEffect
if (mSharing && info.name && *info.name)
{
auto it = mEffectNormalMap.find(info.name);
if (mSharing && it != mEffectNormalMap.end())
{
return it->second;
}
}
auto effect = std::make_shared<NormalMapEffect>(mDevice.Get());
SetMaterialProperties(effect.get(), info);
if (info.perVertexColor)
{
effect->SetVertexColorEnabled(true);
}
if (info.diffuseTexture && *info.diffuseTexture)
{
ComPtr<ID3D11ShaderResourceView> srv;
factory->CreateTexture(info.diffuseTexture, deviceContext, srv.GetAddressOf());
effect->SetTexture(srv.Get());
}
if (info.specularTexture && *info.specularTexture)
{
ComPtr<ID3D11ShaderResourceView> srv;
factory->CreateTexture(info.specularTexture, deviceContext, srv.GetAddressOf());
effect->SetSpecularTexture(srv.Get());
}
if (info.normalTexture && *info.normalTexture)
{
ComPtr<ID3D11ShaderResourceView> srv;
factory->CreateTexture(info.normalTexture, deviceContext, srv.GetAddressOf());
effect->SetNormalTexture(srv.Get());
}
if (mSharing && info.name && *info.name)
{
std::lock_guard<std::mutex> lock(mutex);
EffectCache::value_type v(info.name, effect);
mEffectNormalMap.insert(v);
}
return std::move(effect);
}
else
{
// BasicEffect
if (mSharing && info.name && *info.name)
{
auto it = mEffectCache.find(info.name);
if (mSharing && it != mEffectCache.end())
{
return it->second;
}
}
auto effect = std::make_shared<BasicEffect>(mDevice.Get());
effect->SetLightingEnabled(true);
SetMaterialProperties(effect.get(), info);
if (info.perVertexColor)
{
effect->SetVertexColorEnabled(true);
}
if (info.diffuseTexture && *info.diffuseTexture)
{
ComPtr<ID3D11ShaderResourceView> srv;
factory->CreateTexture(info.diffuseTexture, deviceContext, srv.GetAddressOf());
effect->SetTexture(srv.Get());
effect->SetTextureEnabled(true);
}
if (mSharing && info.name && *info.name)
{
std::lock_guard<std::mutex> lock(mutex);
EffectCache::value_type v(info.name, effect);
mEffectCache.insert(v);
}
return std::move(effect);
}
}