Created
October 13, 2023 04:13
-
-
Save pollend/fbb4b9299da95e6966505ded72d12366 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cMaterial* cMaterialManager::LoadFromFile(const tString& asName, const tWString& asPath) { | |
tinyxml2::XMLDocument document; | |
FILE *pFile = cPlatform::OpenFile(asPath, _W("rb")); | |
if(!pFile) { | |
LOGF(LogLevel::eERROR, "failed to load material: %s", asName.c_str()); | |
return nullptr; | |
} | |
document.LoadFile(pFile); | |
fclose(pFile); | |
auto* rootElement = document.FirstChildElement(); | |
if (rootElement == nullptr) { | |
LOGF(LogLevel::eERROR,"Material-%s: Root not found", asName.c_str()); | |
return nullptr; | |
} | |
auto* mainElement = rootElement->FirstChildElement("Main"); | |
if (mainElement == nullptr) { | |
LOGF(LogLevel::eERROR,"Material-%s: Main child not found", asName.c_str()); | |
return nullptr; | |
} | |
const char* sType = ""; | |
if(mainElement->QueryAttribute("Type", &sType) != tinyxml2::XMLError::XML_SUCCESS) { | |
LOGF(LogLevel::eERROR,"Material-%s:Missing Type Attribute: ", asName.c_str()); | |
return nullptr; | |
} | |
bool bDepthTest = true; | |
float fValue = 1; | |
const char* sPhysicsMatName = "Default"; //pMain->GetAttributeString("PhysicsMaterial", "Default"); | |
const char* sBlendMode = "Add"; //pMain->GetAttributeString("BlendMode", "Add"); | |
mainElement->QueryBoolAttribute("DepthTest", &bDepthTest); | |
mainElement->QueryFloatAttribute("Value", &fValue); | |
mainElement->QueryStringAttribute("PhysicsMaterial", &sPhysicsMatName); | |
mainElement->QueryStringAttribute("BlendMode", &sBlendMode); | |
///////////////////////////// | |
// Make a "fake" material, with a blank type | |
if (mbDisableRenderDataLoading) { | |
cMaterial* pMat = hplNew(cMaterial, (asName, asPath, mpResources)); | |
pMat->SetPhysicsMaterial(sPhysicsMatName); | |
return pMat; | |
} | |
///////////////////////////// | |
// CreateType | |
tString normalizedMaterialName = cString::ToLowerCase(sType); | |
auto metaInfo = std::find_if(cMaterial::MaterialMetaTable.begin(), cMaterial::MaterialMetaTable.end(), [&](auto& info) { | |
return info.m_name == normalizedMaterialName; | |
}); | |
if (metaInfo == cMaterial::MaterialMetaTable.end()) { | |
LOGF(eERROR, "Invalid material type %s", sType); | |
return NULL; | |
} | |
cMaterial* pMat = new cMaterial(asName, asPath, mpResources); | |
pMat->SetDepthTest(bDepthTest); | |
pMat->SetPhysicsMaterial(sPhysicsMatName); | |
/////////////////////////// | |
// Textures | |
auto* textureUnits = rootElement->FirstChildElement("TextureUnits"); | |
if (textureUnits == nullptr) { | |
LOGF(LogLevel::eERROR,"Material-%s: TextureUnits child not found", asName.c_str()); | |
return NULL; | |
} | |
for (eMaterialTexture textureType : metaInfo->m_usedTextures) { | |
tString sTextureType = GetTextureString(textureType); | |
auto* pTexChild = textureUnits->FirstChildElement(sTextureType.c_str()); | |
if (pTexChild == NULL) { | |
continue; | |
} | |
bool bMipMaps = true; | |
bool bCompress = false; | |
const char* textureTypeStr = ""; | |
const char* wrapStr = ""; | |
const char* sFileQuery = ""; | |
const char* animModeStr = "None"; | |
float fFrameTime = 1.0f; | |
pTexChild->QueryStringAttribute("AnimMode", &animModeStr); | |
pTexChild->QueryStringAttribute("Wrap", &wrapStr); | |
pTexChild->QueryStringAttribute("Type", &textureTypeStr); | |
pTexChild->QueryStringAttribute("File", &sFileQuery ); | |
pTexChild->QueryBoolAttribute("MipMaps", &bMipMaps); | |
pTexChild->QueryBoolAttribute("Compress", &bCompress); | |
pTexChild->QueryFloatAttribute("AnimFrameTime", &fFrameTime); | |
eTextureWrap wrap = GetWrap(wrapStr); | |
eTextureType type = GetType(textureTypeStr); | |
eTextureAnimMode animMode = GetAnimMode(animModeStr); | |
if (strcmp(sFileQuery ,"")) { | |
continue; | |
} | |
tString sFile = sFileQuery; | |
if (cString::GetFilePath(sFile).length() <= 1) { | |
sFile = cString::SetFilePath(sFile, cString::To8Char(cString::GetFilePathW(asPath))); | |
} | |
cTextureManager::ImageOptions options; | |
iResourceBase* pImageResource = nullptr; | |
if (animMode != eTextureAnimMode_None) { | |
auto animatedImage = mpResources->GetTextureManager()->CreateAnimImage( | |
sFile, bMipMaps, type, eTextureUsage_Normal, mlTextureSizeDownScaleLevel); | |
animatedImage->SetFrameTime(fFrameTime); | |
animatedImage->SetAnimMode(animMode); | |
pMat->SetImage(textureType, animatedImage); | |
pImageResource = animatedImage; | |
} else { | |
Image* pImage = nullptr; | |
switch (type) { | |
case eTextureType_1D: | |
pImage = | |
mpResources->GetTextureManager()->Create1DImage(sFile, bMipMaps, eTextureUsage_Normal, mlTextureSizeDownScaleLevel); | |
break; | |
case eTextureType_2D: | |
pImage = mpResources->GetTextureManager()->Create2DImage( | |
sFile, bMipMaps, eTextureType_2D, eTextureUsage_Normal, mlTextureSizeDownScaleLevel); | |
break; | |
case eTextureType_CubeMap: | |
pImage = mpResources->GetTextureManager()->CreateCubeMapImage( | |
sFile, bMipMaps, eTextureUsage_Normal, mlTextureSizeDownScaleLevel); | |
break; | |
case eTextureType_3D: | |
pImage = | |
mpResources->GetTextureManager()->Create3DImage(sFile, bMipMaps, eTextureUsage_Normal, mlTextureSizeDownScaleLevel); | |
break; | |
default: | |
{ | |
ASSERT(false && "Invalid texture type"); | |
break; | |
} | |
} | |
pImageResource = pImage; | |
pMat->setTextureWrap(wrap); | |
pMat->setTextureFilter(mTextureFilter); | |
pMat->SetTextureAnisotropy(mfTextureAnisotropy); | |
if (pImage) { | |
pMat->SetImage(textureType, pImage); | |
} | |
} | |
if (!pImageResource) { | |
hplDelete(pMat); | |
return nullptr; | |
} | |
} | |
/////////////////////////// | |
// Animations | |
auto* pUvAnimRoot = rootElement->FirstChildElement("UvAnimations"); | |
if (pUvAnimRoot) { | |
auto animElement = pUvAnimRoot->FirstChildElement(); | |
for(;animElement != nullptr; animElement = animElement->NextSiblingElement()) { | |
const char* animTypeStr = ""; | |
const char* animAxisStr = ""; | |
float fSpeed = 0; | |
float fAmp = 0; | |
auto* animationNode = animElement->ToElement(); | |
animationNode->QueryStringAttribute("Type", &animTypeStr); | |
animationNode->QueryStringAttribute("Axis", &animAxisStr); | |
eMaterialUvAnimation animType = GetUvAnimType(animTypeStr); | |
eMaterialAnimationAxis animAxis = GetAnimAxis(animAxisStr); | |
animationNode->QueryFloatAttribute("Speed", &fSpeed); | |
animationNode->QueryFloatAttribute("Amplitude", &fAmp); | |
pMat->AddUvAnimation(animType, fSpeed, fAmp, animAxis); | |
} | |
} | |
/////////////////////////// | |
// Variables | |
cResourceVarsObject userVars; | |
auto* pUserVarsRoot = rootElement->FirstChildElement("SpecificVariables"); | |
if (pUserVarsRoot) | |
userVars.LoadVariables(pUserVarsRoot); | |
for (auto& meta : cMaterial::MaterialMetaTable) { | |
if (normalizedMaterialName == meta.m_name) { | |
pMat->SetHandle(IndexPoolHandle(&internal::m_MaterialIndexPool)); | |
MaterialDescriptor materialDescriptor; | |
materialDescriptor.m_id = meta.m_id; | |
switch (meta.m_id) { | |
case MaterialID::SolidDiffuse: | |
{ | |
materialDescriptor.m_solid.m_heightMapScale = userVars.GetVarFloat("HeightMapScale", 0.1f); | |
materialDescriptor.m_solid.m_heightMapBias = userVars.GetVarFloat("HeightMapBias", 0); | |
materialDescriptor.m_solid.m_frenselBias = userVars.GetVarFloat("FrenselBias", 0.2f); | |
materialDescriptor.m_solid.m_frenselPow = userVars.GetVarFloat("FrenselPow", 8.0f); | |
materialDescriptor.m_solid.m_alphaDissolveFilter = userVars.GetVarBool("AlphaDissolveFilter", false); | |
break; | |
} | |
case MaterialID::Translucent: | |
{ | |
materialDescriptor.m_translucent.m_hasRefraction = userVars.GetVarBool("Refraction", false); | |
materialDescriptor.m_translucent.m_refractionNormals = userVars.GetVarBool("RefractionNormals", true); | |
materialDescriptor.m_translucent.m_refractionEdgeCheck = userVars.GetVarBool("RefractionEdgeCheck", true); | |
materialDescriptor.m_translucent.m_isAffectedByLightLevel = userVars.GetVarBool("AffectedByLightLevel", false); | |
materialDescriptor.m_translucent.m_refractionScale = userVars.GetVarFloat("RefractionScale", 1.0f); | |
materialDescriptor.m_translucent.m_frenselBias = userVars.GetVarFloat("FrenselBias", 0.2f); | |
materialDescriptor.m_translucent.m_frenselPow = userVars.GetVarFloat("FrenselPow", 8.0); | |
materialDescriptor.m_translucent.m_rimLightMul = userVars.GetVarFloat("RimLightMul", 0.0f); | |
materialDescriptor.m_translucent.m_rimLightPow = userVars.GetVarFloat("RimLightPow", 8.0f); | |
materialDescriptor.m_translucent.m_blend = GetBlendMode(sBlendMode); | |
break; | |
} | |
case MaterialID::Water: | |
{ | |
materialDescriptor.m_water.m_hasReflection = userVars.GetVarBool("HasReflection", true); | |
materialDescriptor.m_water.m_refractionScale = userVars.GetVarFloat("RefractionScale", 1.0f); | |
materialDescriptor.m_water.m_frenselBias = userVars.GetVarFloat("FrenselBias", 0.2f); | |
materialDescriptor.m_water.m_frenselPow = userVars.GetVarFloat("FrenselPow", 8.0f); | |
materialDescriptor.m_water.m_reflectionFadeStart = userVars.GetVarFloat("ReflectionFadeStart", 0); | |
materialDescriptor.m_water.m_reflectionFadeEnd = userVars.GetVarFloat("ReflectionFadeEnd", 0); | |
materialDescriptor.m_water.m_waveSpeed = userVars.GetVarFloat("WaveSpeed", 1.0f); | |
materialDescriptor.m_water.m_waveAmplitude = userVars.GetVarFloat("WaveAmplitude", 1.0f); | |
materialDescriptor.m_water.m_waveFreq = userVars.GetVarFloat("WaveFreq", 1.0f); | |
materialDescriptor.m_water.m_isLargeSurface = userVars.GetVarBool("LargeSurface", false); | |
materialDescriptor.m_water.m_worldReflectionOcclusionTest = | |
userVars.GetVarBool("OcclusionCullWorldReflection", true); | |
break; | |
} | |
case MaterialID::Decal: | |
{ | |
materialDescriptor.m_translucent.m_blend = GetBlendMode(sBlendMode); | |
break; | |
} | |
default: | |
ASSERT(false && "Invalid material type"); | |
break; | |
} | |
pMat->SetDescriptor(materialDescriptor); | |
break; | |
} | |
} | |
return pMat; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment