Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ShaderDefines.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 "ShaderDefines.h"
21 
22 #include "maths/Vector4D.h"
23 #include "ps/ThreadUtil.h"
24 
25 #include <sstream>
26 
27 size_t hash_value(const CStrIntern& v)
28 {
29  return v.GetHash();
30 }
31 
32 size_t hash_value(const CVector4D& v)
33 {
34  size_t hash = 0;
35  boost::hash_combine(hash, v.X);
36  boost::hash_combine(hash, v.Y);
37  boost::hash_combine(hash, v.Z);
38  boost::hash_combine(hash, v.W);
39  return hash;
40 }
41 
43 {
44  return items.hash;
45 }
46 
48 {
49  return items.hash;
50 }
51 
53 {
54  return a.items == b.items;
55 }
56 
58 {
59  return a.items == b.items;
60 }
61 
62 template<typename value_t>
64 {
66 
69  bool operator()(const Item& a, const Item& b) const
70  {
71  return a.first < b.first;
72  }
73 };
74 
75 template<typename value_t>
77 {
79 
80  bool operator()(const Item& a, const Item& b) const
81  {
82  return !(b.first < a.first);
83  }
84 };
85 
86 template<typename value_t>
88 {
89  ENSURE(ThreadUtil::IsMainThread()); // s_InternedItems is not thread-safe
90 
91  typename InternedItems_t::iterator it = s_InternedItems.find(items);
92  if (it != s_InternedItems.end())
93  return it->second.get();
94 
95  // Sanity test: the items list is meant to be sorted by name.
96  // This is a reasonable place to verify that, since this will be called once per distinct SItems.
97  typedef ItemNameCmp<value_t> Cmp;
98  ENSURE(std::adjacent_find(items.items.begin(), items.items.end(), std::binary_negate<Cmp>(Cmp())) == items.items.end());
99 
100  shared_ptr<SItems> ptr(new SItems(items));
101  s_InternedItems.insert(std::make_pair(items, ptr));
102  return ptr.get();
103 }
104 
105 template<typename value_t>
107 {
108  *this = s_Empty;
109 }
110 
111 template<typename value_t>
113 {
114 }
115 
116 template<typename value_t>
118 {
119  SItems items;
120  items.RecalcHash();
121  return CShaderParams(GetInterned(items));
122 }
123 
124 template<typename value_t>
125 void CShaderParams<value_t>::Set(CStrIntern name, const value_t& value)
126 {
127  SItems items = *m_Items;
128 
129  typename SItems::Item addedItem = std::make_pair(name, value);
130 
131  // Add the new item in a way that preserves the sortedness and uniqueness of item names
132  for (typename std::vector<typename SItems::Item>::iterator it = items.items.begin(); ; ++it)
133  {
134  if (it == items.items.end() || addedItem.first < it->first)
135  {
136  items.items.insert(it, addedItem);
137  break;
138  }
139  else if (addedItem.first == it->first)
140  {
141  it->second = addedItem.second;
142  break;
143  }
144  }
145 
146  items.RecalcHash();
147  m_Items = GetInterned(items);
148 }
149 
150 template<typename value_t>
152 {
153  SItems items;
154  // set_union merges the two sorted lists into a new sorted list;
155  // if two items are equivalent (i.e. equal names, possibly different values)
156  // then the one from the first list is kept
157  std::set_union(
158  params.m_Items->items.begin(), params.m_Items->items.end(),
159  m_Items->items.begin(), m_Items->items.end(),
160  std::inserter(items.items, items.items.begin()),
162  items.RecalcHash();
163  m_Items = GetInterned(items);
164 }
165 
166 template<typename value_t>
167 std::map<CStrIntern, value_t> CShaderParams<value_t>::GetMap() const
168 {
169  std::map<CStrIntern, value_t> ret;
170  for (size_t i = 0; i < m_Items->items.size(); ++i)
171  ret[m_Items->items[i].first] = m_Items->items[i].second;
172  return ret;
173 }
174 
175 template<typename value_t>
177 {
178  return m_Items->hash;
179 }
180 
181 template<typename value_t>
183 {
184  size_t h = 0;
185  for (size_t i = 0; i < items.size(); ++i)
186  {
187  boost::hash_combine(h, items[i].first);
188  boost::hash_combine(h, items[i].second);
189  }
190  hash = h;
191 }
192 
193 
195 {
196  Set(name, value);
197 }
198 
199 int CShaderDefines::GetInt(const char* name) const
200 {
201  CStrIntern nameIntern(name);
202  for (size_t i = 0; i < m_Items->items.size(); ++i)
203  {
204  if (m_Items->items[i].first == nameIntern)
205  {
206  int ret;
207  std::stringstream str(m_Items->items[i].second.c_str());
208  str >> ret;
209  return ret;
210  }
211  }
212  return 0;
213 }
214 
215 
216 void CShaderUniforms::Add(const char* name, const CVector4D& value)
217 {
218  Set(CStrIntern(name), value);
219 }
220 
221 CVector4D CShaderUniforms::GetVector(const char* name) const
222 {
223  CStrIntern nameIntern(name);
224  for (size_t i = 0; i < m_Items->items.size(); ++i)
225  {
226  if (m_Items->items[i].first == nameIntern)
227  {
228  return m_Items->items[i].second;
229  }
230  }
231  return CVector4D();
232 }
233 
235 {
236  const std::vector<SItems::Item>& items = m_Items->items;
237  for (size_t i = 0; i < items.size(); ++i)
238  {
239  CShaderProgram::Binding binding = shader->GetUniformBinding(items[i].first);
240  if (binding.Active())
241  {
242  CVector4D v = items[i].second;
243  shader->Uniform(binding, v.X, v.Y, v.Z, v.W);
244  }
245  }
246 }
247 
248 void CShaderRenderQueries::Add(const char* name)
249 {
250  if (name == CStr("sim_time"))
251  {
252  m_Items.push_back(std::make_pair(RQUERY_TIME, CStrIntern(name)));
253  }
254  else if (name == CStr("water_tex"))
255  {
256  m_Items.push_back(std::make_pair(RQUERY_WATER_TEX, CStrIntern(name)));
257  }
258  else if (name == CStr("sky_cube"))
259  {
260  m_Items.push_back(std::make_pair(RQUERY_SKY_CUBE, CStrIntern(name)));
261  }
262 }
263 
264 void CShaderConditionalDefines::Add(const char* defname, const char* defvalue, int type, std::vector<float> &args)
265 {
266  CondDefine cd;
267  cd.m_DefName = CStrIntern(defname);
268  cd.m_DefValue = CStrIntern(defvalue);
269  cd.m_CondArgs = args;
270  cd.m_CondType = type;
271 
272  m_Defines.push_back(cd);
273 }
274 
275 
276 // Explicit instantiations:
277 
280 
283 
284 template class CShaderParams<CStrIntern>;
285 template class CShaderParams<CVector4D>;
std::pair< CStrIntern, value_t > Item
Definition: ShaderDefines.h:98
void Add(CStrIntern name, CStrIntern value)
Add a name and associated value to the map of defines.
void Add(const char *name, const CVector4D &value)
Add a name and associated value to the map of uniforms.
size_t hash_value(const CStrIntern &v)
bool operator==(const FCDJointWeightPair &a, const FCDJointWeightPair &b)
Definition: GeomReindex.cpp:59
CShaderParams< value_t >::SItems::Item Item
std::map< CStrIntern, value_t > GetMap() const
Return a copy of the current name/value mapping.
float Y
Definition: Vector4D.h:128
u32 GetHash() const
Returns cached FNV1-A hash of the string.
Definition: CStrIntern.cpp:135
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
bool operator()(const Item &a, const Item &b) const
boost::unordered_map< SItems, shared_ptr< SItems > > InternedItems_t
float Z
Definition: Vector4D.h:128
Interned 8-bit strings.
Definition: CStrIntern.h:37
void BindUniforms(const CShaderProgramPtr &shader) const
Bind the collection of uniforms onto the given shader.
CShaderParams()
Create an empty map of defines.
static CShaderParams CreateEmpty()
bool operator()(const Item &a, const Item &b) const
void Add(const char *name)
CVector4D GetVector(const char *name) const
Return the value for the given name, or (0,0,0,0) if not defined.
SItems * m_Items
size_t GetHash() const
Return a hash of the current mapping.
Represents a mapping of name strings to value, for use with CShaderDefines (values are strings) and C...
Definition: ShaderDefines.h:39
void SetMany(const CShaderParams &params)
Add all the names and values from another set of parameters.
float W
Definition: Vector4D.h:128
int GetInt(const char *name) const
Return the value for the given name as an integer, or 0 if not defined.
static SItems * GetInterned(const SItems &items)
Returns a pointer to an SItems equal to items.
CShaderParams< value_t >::SItems::Item Item
Represents a uniform attribute or texture binding.
Item first_argument_type
Item second_argument_type
bool IsMainThread()
Returns whether the current thread is the &#39;main&#39; thread (i.e.
Definition: ThreadUtil.cpp:25
std::vector< Item > items
void Set(CStrIntern name, const value_t &value)
Add a name and associated value to the map of parameters.
shared_ptr< CShaderProgram > CShaderProgramPtr
void Add(const char *defname, const char *defvalue, int type, std::vector< float > &args)
bool Active()
Returns whether this uniform attribute is active in the shader.
float X
Definition: Vector4D.h:128