Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MaterialManager.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2012 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
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.
8  *
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.
13  *
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/>.
16  */
17 
18 #include "precompiled.h"
19 
20 #include "MaterialManager.h"
21 
22 #include "lib/ogl.h"
23 #include "maths/MathUtil.h"
24 #include "maths/Vector4D.h"
25 #include "ps/ConfigDB.h"
26 #include "ps/Filesystem.h"
27 #include "ps/PreprocessorWrapper.h"
28 #include "ps/XML/Xeromyces.h"
29 #include "renderer/Renderer.h"
30 
31 #include <sstream>
32 
34 {
35  qualityLevel = 5.0;
36  CFG_GET_VAL("materialmgr.quality", Float, qualityLevel);
37  qualityLevel = clamp(qualityLevel, 0.0f, 10.0f);
38 }
39 
41 {
42  if (pathname.empty())
43  return CMaterial();
44 
45  std::map<VfsPath, CMaterial>::iterator iter = m_Materials.find(pathname);
46  if (iter != m_Materials.end())
47  return iter->second;
48 
49  CXeromyces xeroFile;
50  if (xeroFile.Load(g_VFS, pathname) != PSRETURN_OK)
51  return CMaterial();
52 
53  #define EL(x) int el_##x = xeroFile.GetElementID(#x)
54  #define AT(x) int at_##x = xeroFile.GetAttributeID(#x)
55  EL(alpha_blending);
56  EL(alternative);
57  EL(define);
58  EL(shader);
59  EL(uniform);
60  EL(renderquery);
61  EL(conditional_define);
62  AT(effect);
63  AT(if);
64  AT(quality);
65  AT(material);
66  AT(name);
67  AT(value);
68  AT(type);
69  AT(min);
70  AT(max);
71  AT(conf);
72  #undef AT
73  #undef EL
74 
75  CMaterial material;
76 
77  XMBElement root = xeroFile.GetRoot();
78 
79  CPreprocessorWrapper preprocessor;
80  preprocessor.AddDefine("CFG_FORCE_ALPHATEST", g_Renderer.m_Options.m_ForceAlphaTest ? "1" : "0");
81 
82  CVector4D vec(qualityLevel,0,0,0);
83  material.AddStaticUniform("qualityLevel", vec);
84 
85  XERO_ITER_EL(root, node)
86  {
87  int token = node.GetNodeName();
88  XMBAttributeList attrs = node.GetAttributes();
89  if (token == el_alternative)
90  {
91  CStr cond = attrs.GetNamedItem(at_if);
92  if (cond.empty() || !preprocessor.TestConditional(cond))
93  {
94  cond = attrs.GetNamedItem(at_quality);
95  if (cond.empty())
96  continue;
97  else
98  {
99  if (cond.ToFloat() <= qualityLevel)
100  continue;
101  }
102  }
103 
104  material = LoadMaterial(VfsPath("art/materials") / attrs.GetNamedItem(at_material).FromUTF8());
105  break;
106  }
107  else if (token == el_alpha_blending)
108  {
109  material.SetUsesAlphaBlending(true);
110  }
111  else if (token == el_shader)
112  {
113  material.SetShaderEffect(attrs.GetNamedItem(at_effect));
114  }
115  else if (token == el_define)
116  {
117  material.AddShaderDefine(CStrIntern(attrs.GetNamedItem(at_name)), CStrIntern(attrs.GetNamedItem(at_value)));
118  }
119  else if (token == el_conditional_define)
120  {
121  std::vector<float> args;
122 
123  CStr type = attrs.GetNamedItem(at_type).c_str();
124  int typeID = -1;
125 
126  if (type == CStr("draw_range"))
127  {
128  typeID = DCOND_DISTANCE;
129 
130  float valmin = -1.0f;
131  float valmax = -1.0f;
132 
133  CStr conf = attrs.GetNamedItem(at_conf);
134  if (!conf.empty())
135  {
136  CFG_GET_VAL("materialmgr." + conf + ".min", Float, valmin);
137  CFG_GET_VAL("materialmgr." + conf + ".max", Float, valmax);
138  }
139  else
140  {
141  CStr dmin = attrs.GetNamedItem(at_min);
142  if (!dmin.empty())
143  valmin = attrs.GetNamedItem(at_min).ToFloat();
144 
145  CStr dmax = attrs.GetNamedItem(at_max);
146  if (!dmax.empty())
147  valmax = attrs.GetNamedItem(at_max).ToFloat();
148  }
149 
150  args.push_back(valmin);
151  args.push_back(valmax);
152 
153  if (valmin >= 0.0f)
154  {
155  std::stringstream sstr;
156  sstr << valmin;
157  material.AddShaderDefine(CStrIntern(conf + "_MIN"), CStrIntern(sstr.str()));
158  }
159 
160  if (valmax >= 0.0f)
161  {
162  std::stringstream sstr;
163  sstr << valmax;
164  material.AddShaderDefine(CStrIntern(conf + "_MAX"), CStrIntern(sstr.str()));
165  }
166  }
167 
168  material.AddConditionalDefine(attrs.GetNamedItem(at_name).c_str(),
169  attrs.GetNamedItem(at_value).c_str(),
170  typeID, args);
171  }
172  else if (token == el_uniform)
173  {
174  std::stringstream str(attrs.GetNamedItem(at_value));
175  CVector4D vec;
176  str >> vec.X >> vec.Y >> vec.Z >> vec.W;
177  material.AddStaticUniform(attrs.GetNamedItem(at_name).c_str(), vec);
178  }
179  else if (token == el_renderquery)
180  {
181  material.AddRenderQuery(attrs.GetNamedItem(at_name).c_str());
182  }
183  }
184 
186 
187  m_Materials[pathname] = material;
188  return material;
189 }
void AddShaderDefine(CStrIntern key, CStrIntern value)
Definition: Material.cpp:35
Path VfsPath
VFS path of the form &quot;(dir/)*file?&quot;.
Definition: vfs_path.h:40
const PSRETURN PSRETURN_OK
Definition: Errors.h:103
#define AT(x)
#define CFG_GET_VAL(name, type, destination)
Definition: ConfigDB.h:147
#define EL(x)
void AddConditionalDefine(const char *defname, const char *defvalue, int type, std::vector< float > &args)
Definition: Material.cpp:41
#define XERO_ITER_EL(parent_element, child_element)
Definition: Xeromyces.h:91
bool TestConditional(const CStr &expr)
void SetUsesAlphaBlending(bool flag)
Definition: Material.h:47
#define g_Renderer
Definition: Renderer.h:61
void SetShaderEffect(const CStr &effect)
Definition: Material.cpp:30
Interned 8-bit strings.
Definition: CStrIntern.h:37
Definition: path.h:75
CStr8 GetNamedItem(const int AttributeName) const
Definition: XeroXMB.cpp:259
std::map< VfsPath, CMaterial > m_Materials
bool empty() const
Definition: path.h:118
void AddDefine(const char *name, const char *value)
void AddRenderQuery(const char *key)
Definition: Material.cpp:59
Convenience wrapper around CPreprocessor.
void RecomputeCombinedShaderDefines()
Definition: Material.cpp:70
PIVFS g_VFS
Definition: Filesystem.cpp:30
void AddStaticUniform(const char *key, const CVector4D &value)
Definition: Material.cpp:47
T clamp(T value, T min, T max)
Definition: MathUtil.h:32
float X
Definition: Vector4D.h:128
CMaterial LoadMaterial(const VfsPath &pathname)