1 /* Copyright (C) 2022 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #include "precompiled.h"
20 #include "MaterialManager.h"
22 #include "graphics/PreprocessorWrapper.h"
23 #include "maths/MathUtil.h"
24 #include "maths/Vector4D.h"
25 #include "ps/CLogger.h"
26 #include "ps/ConfigDB.h"
27 #include "ps/CStrInternStatic.h"
28 #include "ps/Filesystem.h"
29 #include "ps/XML/Xeromyces.h"
30 #include "renderer/RenderingOptions.h"
34 CMaterialManager::CMaterialManager()
37 CFG_GET_VAL("materialmgr.quality", qualityLevel
);
38 qualityLevel
= Clamp(qualityLevel
, 0.0f
, 10.0f
);
40 if (VfsDirectoryExists(L
"art/materials/") && !CXeromyces::AddValidator(g_VFS
, "material", "art/materials/material.rng"))
41 LOGERROR("CMaterialManager: failed to load grammar file 'art/materials/material.rng'");
44 CMaterial
CMaterialManager::LoadMaterial(const VfsPath
& pathname
)
49 std::map
<VfsPath
, CMaterial
>::iterator iter
= m_Materials
.find(pathname
);
50 if (iter
!= m_Materials
.end())
54 if (xeroFile
.Load(g_VFS
, pathname
, "material") != PSRETURN_OK
)
57 #define EL(x) int el_##x = xeroFile.GetElementID(#x)
58 #define AT(x) int at_##x = xeroFile.GetAttributeID(#x)
76 CPreprocessorWrapper preprocessor
;
78 material
.AddStaticUniform("qualityLevel", CVector4D(qualityLevel
, 0, 0, 0));
80 XMBElement root
= xeroFile
.GetRoot();
81 XERO_ITER_EL(root
, node
)
83 int token
= node
.GetNodeName();
84 XMBAttributeList attrs
= node
.GetAttributes();
85 if (token
== el_alternative
)
87 CStr cond
= attrs
.GetNamedItem(at_if
);
88 if (cond
.empty() || !preprocessor
.TestConditional(cond
))
90 cond
= attrs
.GetNamedItem(at_quality
);
95 if (cond
.ToFloat() <= qualityLevel
)
100 material
= LoadMaterial(VfsPath("art/materials") / attrs
.GetNamedItem(at_material
).FromUTF8());
103 else if (token
== el_alpha_blending
)
105 material
.SetUsesAlphaBlending(true);
107 else if (token
== el_shader
)
109 material
.SetShaderEffect(attrs
.GetNamedItem(at_effect
));
111 else if (token
== el_define
)
113 material
.AddShaderDefine(CStrIntern(attrs
.GetNamedItem(at_name
)), CStrIntern(attrs
.GetNamedItem(at_value
)));
115 else if (token
== el_uniform
)
117 std::stringstream
str(attrs
.GetNamedItem(at_value
));
119 str
>> vec
.X
>> vec
.Y
>> vec
.Z
>> vec
.W
;
120 material
.AddStaticUniform(attrs
.GetNamedItem(at_name
).c_str(), vec
);
122 else if (token
== el_renderquery
)
124 material
.AddRenderQuery(attrs
.GetNamedItem(at_name
).c_str());
126 else if (token
== el_required_texture
)
128 material
.AddRequiredSampler(attrs
.GetNamedItem(at_name
));
129 if (!attrs
.GetNamedItem(at_define
).empty())
130 material
.AddShaderDefine(CStrIntern(attrs
.GetNamedItem(at_define
)), str_1
);
134 m_Materials
[pathname
] = material
;