Hey, today I'll show you how to load normal maps from any file format (I'll assume you're using assimp which supports most of the popular model formats.)
The problem with most of the formats is that they don't support more than 1 texture per subset in model, so the solution to this problem is using a prefix or different extension for normal maps and other maps and then getting normal map from the name of diffuse map. I use _NRM prefix for normal maps and _OCC prefix for Ambient Occlusion maps.
Here is my code (NOTE: your diffuse map and normal map must have same name but different prefix/extension i.e your diffuse map is brick.dds and your normal map for it is brick_NRM.dds/bricks.nmap or whatever.)
static std::string removeExtension(std::string filename) {
size_t lastdot = filename.find_last_of(".");
if (lastdot == std::string::npos) return filename;
return filename.substr(0, lastdot);
}
//.............
if (Mat->GetTextureCount(aiTextureType_DIFFUSE) > 0 && Mat->GetTexture(aiTextureType_DIFFUSE, 0, &path) == AI_SUCCESS)
{
std::string file = path.C_Str();
std::string NoExtension = removeExtension(file);
std::string newName = NoExtension + ".dds";
newName = "Resources\\Textures\\" + newName;
ID3D11ShaderResourceView* srv = mInfo.Mgr->CreateTexture(newName);
DiffuseMapSRV.push_back(srv);
}
std::string file = path.C_Str();
std::string NoExtension = removeExtension(file);
std::string NormalMapTexturePath = NoExtension + "_NRM"; //add normal map prefix
NormalMapTexturePath = NormalMapTexturePath + ".dds"; //add extension
std::string AmbientOcclusionMapTexturePath = NoExtension + "_OCC"; //add occlusion map prefix
AmbientOcclusionMapTexturePath = AmbientOcclusionMapTexturePath + ".dds"; //add extension
//finally add full path
NormalMapTexturePath = "Resources\\Textures\\" + NormalMapTexturePath;
AmbientOcclusionMapTexturePath = "Resources\\Textures\\" + AmbientOcclusionMapTexturePath;
ID3D11ShaderResourceView* srv = mInfo.Mgr->CreateTexture(NormalMapTexturePath);
NormalMapSRV.push_back(srv);
if (AOMap)
{
srv = mInfo.Mgr->CreateTexture(AmbientOcclusionMapTexturePath);
AOMapSRV.push_back(srv);
}