Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ShaderManager.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 "ShaderManager.h"
21 
23 #include "lib/timer.h"
24 #include "lib/utf8.h"
25 #include "ps/CLogger.h"
26 #include "ps/CStrIntern.h"
27 #include "ps/Filesystem.h"
28 #include "ps/PreprocessorWrapper.h"
29 #include "ps/Profile.h"
30 #include "ps/XML/Xeromyces.h"
31 #include "ps/XML/XMLWriter.h"
32 #include "renderer/Renderer.h"
33 
34 TIMER_ADD_CLIENT(tc_ShaderValidation);
35 
37 {
38  template<typename S, typename T> bool operator()(const std::pair<S, T>& a, const std::pair<S, T>& b) const
39  {
40  return b.second < a.second;
41  }
42 };
43 
45 {
46 #if USE_SHADER_XML_VALIDATION
47  {
48  TIMER_ACCRUE(tc_ShaderValidation);
49  CVFSFile grammar;
50  if (grammar.Load(g_VFS, L"shaders/program.rng") != PSRETURN_OK)
51  LOGERROR(L"Failed to read grammar shaders/program.rng");
52  else
53  {
54  if (!m_Validator.LoadGrammar(grammar.GetAsString()))
55  LOGERROR(L"Failed to load grammar shaders/program.rng");
56  }
57  }
58 #endif
59 
60  // Allow hotloading of textures
62 }
63 
65 {
67 }
68 
70 {
71  CacheKey key = { name, defines };
72  std::map<CacheKey, CShaderProgramPtr>::iterator it = m_ProgramCache.find(key);
73  if (it != m_ProgramCache.end())
74  return it->second;
75 
76  CShaderProgramPtr program;
77  if (!NewProgram(name, defines, program))
78  {
79  LOGERROR(L"Failed to load shader '%hs'", name);
80  program = CShaderProgramPtr();
81  }
82 
83  m_ProgramCache[key] = program;
84  return program;
85 }
86 
87 static GLenum ParseAttribSemantics(const CStr& str)
88 {
89  // Map known semantics onto the attribute locations documented by NVIDIA
90  if (str == "gl_Vertex") return 0;
91  if (str == "gl_Normal") return 2;
92  if (str == "gl_Color") return 3;
93  if (str == "gl_SecondaryColor") return 4;
94  if (str == "gl_FogCoord") return 5;
95  if (str == "gl_MultiTexCoord0") return 8;
96  if (str == "gl_MultiTexCoord1") return 9;
97  if (str == "gl_MultiTexCoord2") return 10;
98  if (str == "gl_MultiTexCoord3") return 11;
99  if (str == "gl_MultiTexCoord4") return 12;
100  if (str == "gl_MultiTexCoord5") return 13;
101  if (str == "gl_MultiTexCoord6") return 14;
102  if (str == "gl_MultiTexCoord7") return 15;
103 
104  // Define some arbitrary names for user-defined attribute locations
105  // that won't conflict with any standard semantics
106  if (str == "CustomAttribute0") return 1;
107  if (str == "CustomAttribute1") return 6;
108  if (str == "CustomAttribute2") return 7;
109 
110  debug_warn("Invalid attribute semantics");
111  return 0;
112 }
113 
114 bool CShaderManager::NewProgram(const char* name, const CShaderDefines& baseDefines, CShaderProgramPtr& program)
115 {
116  PROFILE2("loading shader");
117  PROFILE2_ATTR("name: %s", name);
118 
119  if (strncmp(name, "fixed:", 6) == 0)
120  {
121  program = CShaderProgramPtr(CShaderProgram::ConstructFFP(name+6, baseDefines));
122  if (!program)
123  return false;
124  program->Reload();
125  return true;
126  }
127 
128  VfsPath xmlFilename = L"shaders/" + wstring_from_utf8(name) + L".xml";
129 
130  CXeromyces XeroFile;
131  PSRETURN ret = XeroFile.Load(g_VFS, xmlFilename);
132  if (ret != PSRETURN_OK)
133  return false;
134 
135 #if USE_SHADER_XML_VALIDATION
136  {
137  TIMER_ACCRUE(tc_ShaderValidation);
138 
139  // Serialize the XMB data and pass it to the validator
140  XML_Start();
141  XML_SetPrettyPrint(false);
142  XML_WriteXMB(XeroFile);
144  if (!ok)
145  return false;
146  }
147 #endif
148 
149  // Define all the elements and attributes used in the XML file
150 #define EL(x) int el_##x = XeroFile.GetElementID(#x)
151 #define AT(x) int at_##x = XeroFile.GetAttributeID(#x)
152  EL(attrib);
153  EL(define);
154  EL(fragment);
155  EL(stream);
156  EL(uniform);
157  EL(vertex);
158  AT(file);
159  AT(if);
160  AT(loc);
161  AT(name);
162  AT(semantics);
163  AT(type);
164  AT(value);
165 #undef AT
166 #undef EL
167 
168  CPreprocessorWrapper preprocessor;
169  preprocessor.AddDefines(baseDefines);
170 
171  XMBElement Root = XeroFile.GetRoot();
172 
173  bool isGLSL = (Root.GetAttributes().GetNamedItem(at_type) == "glsl");
174  VfsPath vertexFile;
175  VfsPath fragmentFile;
176  CShaderDefines defines = baseDefines;
177  std::map<CStrIntern, int> vertexUniforms;
178  std::map<CStrIntern, CShaderProgram::frag_index_pair_t> fragmentUniforms;
179  std::map<CStrIntern, int> vertexAttribs;
180  int streamFlags = 0;
181 
182  XERO_ITER_EL(Root, Child)
183  {
184  if (Child.GetNodeName() == el_define)
185  {
186  defines.Add(CStrIntern(Child.GetAttributes().GetNamedItem(at_name)), CStrIntern(Child.GetAttributes().GetNamedItem(at_value)));
187  }
188  else if (Child.GetNodeName() == el_vertex)
189  {
190  vertexFile = L"shaders/" + Child.GetAttributes().GetNamedItem(at_file).FromUTF8();
191 
192  XERO_ITER_EL(Child, Param)
193  {
194  XMBAttributeList Attrs = Param.GetAttributes();
195 
196  CStr cond = Attrs.GetNamedItem(at_if);
197  if (!cond.empty() && !preprocessor.TestConditional(cond))
198  continue;
199 
200  if (Param.GetNodeName() == el_uniform)
201  {
202  vertexUniforms[CStrIntern(Attrs.GetNamedItem(at_name))] = Attrs.GetNamedItem(at_loc).ToInt();
203  }
204  else if (Param.GetNodeName() == el_stream)
205  {
206  CStr StreamName = Attrs.GetNamedItem(at_name);
207  if (StreamName == "pos")
208  streamFlags |= STREAM_POS;
209  else if (StreamName == "normal")
210  streamFlags |= STREAM_NORMAL;
211  else if (StreamName == "color")
212  streamFlags |= STREAM_COLOR;
213  else if (StreamName == "uv0")
214  streamFlags |= STREAM_UV0;
215  else if (StreamName == "uv1")
216  streamFlags |= STREAM_UV1;
217  else if (StreamName == "uv2")
218  streamFlags |= STREAM_UV2;
219  else if (StreamName == "uv3")
220  streamFlags |= STREAM_UV3;
221  }
222  else if (Param.GetNodeName() == el_attrib)
223  {
224  int attribLoc = ParseAttribSemantics(Attrs.GetNamedItem(at_semantics));
225  vertexAttribs[CStrIntern(Attrs.GetNamedItem(at_name))] = attribLoc;
226  }
227  }
228  }
229  else if (Child.GetNodeName() == el_fragment)
230  {
231  fragmentFile = L"shaders/" + Child.GetAttributes().GetNamedItem(at_file).FromUTF8();
232 
233  XERO_ITER_EL(Child, Param)
234  {
235  XMBAttributeList Attrs = Param.GetAttributes();
236 
237  CStr cond = Attrs.GetNamedItem(at_if);
238  if (!cond.empty() && !preprocessor.TestConditional(cond))
239  continue;
240 
241  if (Param.GetNodeName() == el_uniform)
242  {
243  // A somewhat incomplete listing, missing "shadow" and "rect" versions
244  // which are interpreted as 2D (NB: our shadowmaps may change
245  // type based on user config).
246  GLenum type = GL_TEXTURE_2D;
247  CStr t = Attrs.GetNamedItem(at_type);
248  if (t == "sampler1D")
249  type = GL_TEXTURE_1D;
250  else if (t == "sampler2D")
251  type = GL_TEXTURE_2D;
252  else if (t == "sampler3D")
253  type = GL_TEXTURE_3D;
254  else if (t == "samplerCube")
255  type = GL_TEXTURE_CUBE_MAP;
256 
257  fragmentUniforms[CStrIntern(Attrs.GetNamedItem(at_name))] =
258  std::make_pair(Attrs.GetNamedItem(at_loc).ToInt(), type);
259  }
260  }
261  }
262  }
263 
264  if (isGLSL)
265  program = CShaderProgramPtr(CShaderProgram::ConstructGLSL(vertexFile, fragmentFile, defines, vertexAttribs, streamFlags));
266  else
267  program = CShaderProgramPtr(CShaderProgram::ConstructARB(vertexFile, fragmentFile, defines, vertexUniforms, fragmentUniforms, streamFlags));
268 
269  program->Reload();
270 
271 // m_HotloadFiles[xmlFilename].insert(program); // TODO: should reload somehow when the XML changes
272  m_HotloadFiles[vertexFile].insert(program);
273  m_HotloadFiles[fragmentFile].insert(program);
274 
275  return true;
276 }
277 
278 static GLenum ParseComparisonFunc(const CStr& str)
279 {
280  if (str == "never")
281  return GL_NEVER;
282  if (str == "always")
283  return GL_ALWAYS;
284  if (str == "less")
285  return GL_LESS;
286  if (str == "lequal")
287  return GL_LEQUAL;
288  if (str == "equal")
289  return GL_EQUAL;
290  if (str == "gequal")
291  return GL_GEQUAL;
292  if (str == "greater")
293  return GL_GREATER;
294  if (str == "notequal")
295  return GL_NOTEQUAL;
296  debug_warn("Invalid comparison func");
297  return GL_ALWAYS;
298 }
299 
300 static GLenum ParseBlendFunc(const CStr& str)
301 {
302  if (str == "zero")
303  return GL_ZERO;
304  if (str == "one")
305  return GL_ONE;
306  if (str == "src_color")
307  return GL_SRC_COLOR;
308  if (str == "one_minus_src_color")
309  return GL_ONE_MINUS_SRC_COLOR;
310  if (str == "dst_color")
311  return GL_DST_COLOR;
312  if (str == "one_minus_dst_color")
313  return GL_ONE_MINUS_DST_COLOR;
314  if (str == "src_alpha")
315  return GL_SRC_ALPHA;
316  if (str == "one_minus_src_alpha")
317  return GL_ONE_MINUS_SRC_ALPHA;
318  if (str == "dst_alpha")
319  return GL_DST_ALPHA;
320  if (str == "one_minus_dst_alpha")
321  return GL_ONE_MINUS_DST_ALPHA;
322  if (str == "constant_color")
323  return GL_CONSTANT_COLOR;
324  if (str == "one_minus_constant_color")
325  return GL_ONE_MINUS_CONSTANT_COLOR;
326  if (str == "constant_alpha")
327  return GL_CONSTANT_ALPHA;
328  if (str == "one_minus_constant_alpha")
329  return GL_ONE_MINUS_CONSTANT_ALPHA;
330  if (str == "src_alpha_saturate")
331  return GL_SRC_ALPHA_SATURATE;
332  debug_warn("Invalid blend func");
333  return GL_ZERO;
334 }
335 
337 {
338  size_t hash = 0;
339  boost::hash_combine(hash, key.name.GetHash());
340  boost::hash_combine(hash, key.defines1.GetHash());
341  boost::hash_combine(hash, key.defines2.GetHash());
342  return hash;
343 }
344 
346 {
347  return (name == b.name && defines1 == b.defines1 && defines2 == b.defines2);
348 }
349 
351 {
352  return LoadEffect(name, g_Renderer.GetSystemShaderDefines(), CShaderDefines());
353 }
354 
356 {
357  // Return the cached effect, if there is one
358  EffectCacheKey key = { name, defines1, defines2 };
359  EffectCacheMap::iterator it = m_EffectCache.find(key);
360  if (it != m_EffectCache.end())
361  return it->second;
362 
363  // First time we've seen this key, so construct a new effect:
364 
365  // Merge the two sets of defines, so NewEffect doesn't have to care about the split
366  CShaderDefines defines(defines1);
367  defines.SetMany(defines2);
368 
370  if (!NewEffect(name.c_str(), defines, tech))
371  {
372  LOGERROR(L"Failed to load effect '%hs'", name.c_str());
373  tech = CShaderTechniquePtr();
374  }
375 
376  m_EffectCache[key] = tech;
377  return tech;
378 }
379 
380 bool CShaderManager::NewEffect(const char* name, const CShaderDefines& baseDefines, CShaderTechniquePtr& tech)
381 {
382  PROFILE2("loading effect");
383  PROFILE2_ATTR("name: %s", name);
384 
385  // Shortcut syntax for effects that just contain a single shader
386  if (strncmp(name, "shader:", 7) == 0)
387  {
388  CShaderProgramPtr program = LoadProgram(name+7, baseDefines);
389  if (!program)
390  return false;
391  CShaderPass pass;
392  pass.SetShader(program);
393  tech->AddPass(pass);
394  return true;
395  }
396 
397  VfsPath xmlFilename = L"shaders/effects/" + wstring_from_utf8(name) + L".xml";
398 
399  CXeromyces XeroFile;
400  PSRETURN ret = XeroFile.Load(g_VFS, xmlFilename);
401  if (ret != PSRETURN_OK)
402  return false;
403 
404  // Define all the elements and attributes used in the XML file
405 #define EL(x) int el_##x = XeroFile.GetElementID(#x)
406 #define AT(x) int at_##x = XeroFile.GetAttributeID(#x)
407  EL(alpha);
408  EL(blend);
409  EL(define);
410  EL(depth);
411  EL(pass);
412  EL(require);
413  EL(sort_by_distance);
414  AT(context);
415  AT(dst);
416  AT(func);
417  AT(ref);
418  AT(shader);
419  AT(shaders);
420  AT(src);
421  AT(mask);
422  AT(name);
423  AT(value);
424 #undef AT
425 #undef EL
426 
427  // Read some defines that influence how we pick techniques
428  bool hasARB = (baseDefines.GetInt("SYS_HAS_ARB") != 0);
429  bool hasGLSL = (baseDefines.GetInt("SYS_HAS_GLSL") != 0);
430  bool preferGLSL = (baseDefines.GetInt("SYS_PREFER_GLSL") != 0);
431 
432  // Prepare the preprocessor for conditional tests
433  CPreprocessorWrapper preprocessor;
434  preprocessor.AddDefines(baseDefines);
435 
436  XMBElement Root = XeroFile.GetRoot();
437 
438  // Find all the techniques that we can use, and their preference
439 
440  std::vector<std::pair<XMBElement, int> > usableTechs;
441 
442  XERO_ITER_EL(Root, Technique)
443  {
444  int preference = 0;
445  bool isUsable = true;
446  XERO_ITER_EL(Technique, Child)
447  {
448  XMBAttributeList Attrs = Child.GetAttributes();
449 
450  if (Child.GetNodeName() == el_require)
451  {
452  if (Attrs.GetNamedItem(at_shaders) == "fixed")
453  {
454  // FFP not supported by OpenGL ES
455  #if CONFIG2_GLES
456  isUsable = false;
457  #endif
458  }
459  else if (Attrs.GetNamedItem(at_shaders) == "arb")
460  {
461  if (!hasARB)
462  isUsable = false;
463  }
464  else if (Attrs.GetNamedItem(at_shaders) == "glsl")
465  {
466  if (!hasGLSL)
467  isUsable = false;
468 
469  if (preferGLSL)
470  preference += 100;
471  else
472  preference -= 100;
473  }
474  else if (!Attrs.GetNamedItem(at_context).empty())
475  {
476  CStr cond = Attrs.GetNamedItem(at_context);
477  if (!preprocessor.TestConditional(cond))
478  isUsable = false;
479  }
480  }
481  }
482 
483  if (isUsable)
484  usableTechs.push_back(std::make_pair(Technique, preference));
485  }
486 
487  if (usableTechs.empty())
488  {
489  debug_warn(L"Can't find a usable technique");
490  return false;
491  }
492 
493  // Sort by preference, tie-break on order of specification
494  std::stable_sort(usableTechs.begin(), usableTechs.end(), revcompare2nd());
495 
496  CShaderDefines techDefines = baseDefines;
497 
498  XERO_ITER_EL(usableTechs[0].first, Child)
499  {
500  if (Child.GetNodeName() == el_define)
501  {
502  techDefines.Add(CStrIntern(Child.GetAttributes().GetNamedItem(at_name)), CStrIntern(Child.GetAttributes().GetNamedItem(at_value)));
503  }
504  else if (Child.GetNodeName() == el_sort_by_distance)
505  {
506  tech->SetSortByDistance(true);
507  }
508  else if (Child.GetNodeName() == el_pass)
509  {
510  CShaderDefines passDefines = techDefines;
511 
512  CShaderPass pass;
513 
514  XERO_ITER_EL(Child, Element)
515  {
516  if (Element.GetNodeName() == el_define)
517  {
518  passDefines.Add(CStrIntern(Element.GetAttributes().GetNamedItem(at_name)), CStrIntern(Element.GetAttributes().GetNamedItem(at_value)));
519  }
520  else if (Element.GetNodeName() == el_alpha)
521  {
522  GLenum func = ParseComparisonFunc(Element.GetAttributes().GetNamedItem(at_func));
523  float ref = Element.GetAttributes().GetNamedItem(at_ref).ToFloat();
524  pass.AlphaFunc(func, ref);
525  }
526  else if (Element.GetNodeName() == el_blend)
527  {
528  GLenum src = ParseBlendFunc(Element.GetAttributes().GetNamedItem(at_src));
529  GLenum dst = ParseBlendFunc(Element.GetAttributes().GetNamedItem(at_dst));
530  pass.BlendFunc(src, dst);
531  }
532  else if (Element.GetNodeName() == el_depth)
533  {
534  if (!Element.GetAttributes().GetNamedItem(at_func).empty())
535  pass.DepthFunc(ParseComparisonFunc(Element.GetAttributes().GetNamedItem(at_func)));
536 
537  if (!Element.GetAttributes().GetNamedItem(at_mask).empty())
538  pass.DepthMask(Element.GetAttributes().GetNamedItem(at_mask) == "true" ? 1 : 0);
539  }
540  }
541 
542  // Load the shader program after we've read all the possibly-relevant <define>s
543  pass.SetShader(LoadProgram(Child.GetAttributes().GetNamedItem(at_shader).c_str(), passDefines));
544 
545  tech->AddPass(pass);
546  }
547  }
548 
549  return true;
550 }
551 
553 {
554  return m_EffectCache.size();
555 }
556 
557 /*static*/ Status CShaderManager::ReloadChangedFileCB(void* param, const VfsPath& path)
558 {
559  return static_cast<CShaderManager*>(param)->ReloadChangedFile(path);
560 }
561 
563 {
564  // Find all shaders using this file
565  HotloadFilesMap::iterator files = m_HotloadFiles.find(path);
566  if (files != m_HotloadFiles.end())
567  {
568  // Reload all shaders using this file
569  for (std::set<boost::weak_ptr<CShaderProgram> >::iterator it = files->second.begin(); it != files->second.end(); ++it)
570  {
571  if (shared_ptr<CShaderProgram> program = it->lock())
572  program->Reload();
573  }
574  }
575 
576  // TODO: hotloading changes to shader XML files and effect XML files would be nice
577 
578  return INFO::OK;
579 }
void Add(CStrIntern name, CStrIntern value)
Add a name and associated value to the map of defines.
static GLenum ParseComparisonFunc(const CStr &str)
#define XML_GetOutput()
Definition: XMLWriter.h:102
PSRETURN Load(const PIVFS &vfs, const VfsPath &filename)
Load from an XML file (with invisible XMB caching).
Definition: Xeromyces.cpp:65
const Status OK
Definition: status.h:386
#define LOGERROR
Definition: CLogger.h:35
#define XML_Start()
Definition: XMLWriter.h:71
const PSRETURN PSRETURN_OK
Definition: Errors.h:103
Reads a file, then gives read-only access to the contents.
Definition: Filesystem.h:69
static GLenum ParseAttribSemantics(const CStr &str)
HotloadFilesMap m_HotloadFiles
bool operator()(const std::pair< S, T > &a, const std::pair< S, T > &b) const
void AlphaFunc(GLenum func, GLclampf ref)
XMBAttributeList GetAttributes() const
Definition: XeroXMB.cpp:185
#define XERO_ITER_EL(parent_element, child_element)
Definition: Xeromyces.h:91
bool TestConditional(const CStr &expr)
Key for effect cache lookups.
shared_ptr< CShaderTechnique > CShaderTechniquePtr
#define EL(x)
std::map< CacheKey, CShaderProgramPtr > m_ProgramCache
Definition: ShaderManager.h:94
static CShaderProgram * ConstructARB(const VfsPath &vertexFile, const VfsPath &fragmentFile, const CShaderDefines &defines, const std::map< CStrIntern, int > &vertexIndexes, const std::map< CStrIntern, frag_index_pair_t > &fragmentIndexes, int streamflags)
Construct based on ARB vertex/fragment program files.
bool NewEffect(const char *name, const CShaderDefines &defines, CShaderTechniquePtr &tech)
Status ReloadChangedFile(const VfsPath &path)
#define g_Renderer
Definition: Renderer.h:61
Implements a render pass consisting of various GL state changes and a shader, used by CShaderTechniqu...
#define TIMER_ACCRUE(client)
Measure the time taken to execute code up until end of the current scope; bill it to the given TimerC...
Definition: timer.h:389
static CShaderProgram * ConstructFFP(const std::string &id, const CShaderDefines &defines)
Construct an instance of a pre-defined fixed-function pipeline setup.
u32 GetHash() const
Returns cached FNV1-A hash of the string.
Definition: CStrIntern.cpp:135
CStr GetAsString() const
Returns contents of file as a string.
Definition: Filesystem.cpp:148
const char * c_str() const
Returns null-terminated string.
Definition: CStrIntern.cpp:140
#define PROFILE2(region)
Starts timing from now until the end of the current scope.
Definition: Profiler2.h:446
void BlendFunc(GLenum src, GLenum dst)
Interned 8-bit strings.
Definition: CStrIntern.h:37
void UnregisterFileReloadFunc(FileReloadFunc func, void *obj)
delete a callback function registered with RegisterFileReloadFunc (removes any with the same func and...
Definition: Filesystem.cpp:44
u32 PSRETURN
Definition: Errors.h:75
void RegisterFileReloadFunc(FileReloadFunc func, void *obj)
register a callback function to be called by ReloadChangedFiles
Definition: Filesystem.cpp:39
Definition: path.h:75
CShaderTechniquePtr LoadEffect(CStrIntern name, const CShaderDefines &defines1, const CShaderDefines &defines2)
Load a shader effect.
EffectCacheMap m_EffectCache
#define XML_SetPrettyPrint(enabled)
Definition: XMLWriter.h:74
pthread_key_t key
Definition: wpthread.cpp:140
Implements a render technique consisting of a sequence of passes.
i64 Status
Error handling system.
Definition: status.h:171
#define XML_WriteXMB(xero)
Definition: XMLWriter.h:94
CStr8 GetNamedItem(const int AttributeName) const
Definition: XeroXMB.cpp:259
bool operator==(const EffectCacheKey &b) const
RelaxNGValidator m_Validator
void DepthFunc(GLenum func)
size_t GetHash() const
Return a hash of the current mapping.
std::wstring wstring_from_utf8(const std::string &src, Status *err)
convert UTF-8 to a wide string (UTF-16 or UCS-4, depending on the platform&#39;s wchar_t).
Definition: utf8.cpp:225
static Status ReloadChangedFileCB(void *param, const VfsPath &path)
Represents a mapping of name strings to value strings, for use with #if and #ifdef and similar condit...
static GLenum ParseBlendFunc(const CStr &str)
#define PROFILE2_ATTR
Associates a string (with printf-style formatting) with the current region or event.
Definition: Profiler2.h:461
void AddDefines(const CShaderDefines &defines)
void SetMany(const CShaderParams &params)
Add all the names and values from another set of parameters.
void DepthMask(GLboolean mask)
#define TIMER_ADD_CLIENT(id)
&quot;allocate&quot; a new TimerClient that will keep track of the total time billed to it, along with a descri...
Definition: timer.h:308
XMBElement GetRoot() const
Definition: XeroXMB.cpp:84
int GetInt(const char *name) const
Return the value for the given name as an integer, or 0 if not defined.
PSRETURN Load(const PIVFS &vfs, const VfsPath &filename)
Returns either PSRETURN_OK or PSRETURN_CVFSFile_LoadFailed.
Definition: Filesystem.cpp:117
bool LoadGrammar(const std::string &grammar)
Definition: RelaxNG.cpp:71
#define debug_warn(expr)
display the error dialog with the given text.
Definition: debug.h:324
CShaderProgramPtr LoadProgram(const char *name, const CShaderDefines &defines)
Load a shader program.
size_t GetNumEffectsLoaded()
Returns the number of shader effects that are currently loaded.
size_t operator()(const EffectCacheKey &key) const
Convenience wrapper around CPreprocessor.
PIVFS g_VFS
Definition: Filesystem.cpp:30
bool NewProgram(const char *name, const CShaderDefines &defines, CShaderProgramPtr &program)
void SetShader(const CShaderProgramPtr &shader)
Set the shader program used for rendering with this pass.
static CShaderProgram * ConstructGLSL(const VfsPath &vertexFile, const VfsPath &fragmentFile, const CShaderDefines &defines, const std::map< CStrIntern, int > &vertexAttribs, int streamflags)
Construct based on GLSL vertex/fragment shader files.
shared_ptr< CShaderProgram > CShaderProgramPtr
#define AT(x)
Shader manager: loads and caches shader programs.
Definition: ShaderManager.h:42
bool ValidateEncoded(const std::wstring &filename, const std::string &document)
Definition: RelaxNG.cpp:105