Merge 'remotes/trunk'
[0ad.git] / source / graphics / ShaderDefines.h
blob2d91cd1ac813f627823ba669a44b3cff8edbb012
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 #ifndef INCLUDED_SHADERDEFINES
19 #define INCLUDED_SHADERDEFINES
21 #include "ps/CStr.h"
22 #include "ps/CStrIntern.h"
23 #include "renderer/backend/IDeviceCommandContext.h"
24 #include "renderer/backend/IShaderProgram.h"
26 #include <map>
27 #include <unordered_map>
28 #include <vector>
30 class CVector4D;
32 /**
33 * Represents a mapping of name strings to value, for use with
34 * CShaderDefines (values are strings) and CShaderUniforms (values are vec4s).
36 * Stored as interned vectors of name-value pairs, to support high performance
37 * comparison operators.
39 * Not thread-safe - must only be used from the main thread.
41 template<typename value_t>
42 class CShaderParams
44 public:
45 /**
46 * Create an empty map of defines.
48 CShaderParams();
50 /**
51 * Add a name and associated value to the map of parameters.
52 * If the name is already defined, its value will be replaced.
54 void Set(CStrIntern name, const value_t& value);
56 /**
57 * Add all the names and values from another set of parameters.
58 * If any name is already defined in this object, its value will be replaced.
60 void SetMany(const CShaderParams& params);
62 /**
63 * Return a copy of the current name/value mapping.
65 std::map<CStrIntern, value_t> GetMap() const;
67 /**
68 * Return a hash of the current mapping.
70 size_t GetHash() const;
72 /**
73 * Compare with some arbitrary total order.
74 * The order may be different each time the application is run
75 * (it is based on interned memory addresses).
77 bool operator<(const CShaderParams& b) const
79 return m_Items < b.m_Items;
82 /**
83 * Fast equality comparison.
85 bool operator==(const CShaderParams& b) const
87 return m_Items == b.m_Items;
90 /**
91 * Fast inequality comparison.
93 bool operator!=(const CShaderParams& b) const
95 return m_Items != b.m_Items;
98 struct SItems
100 // Name/value pair
101 using Item = std::pair<CStrIntern, value_t>;
103 // Sorted by name; no duplicated names
104 std::vector<Item> items;
106 size_t hash;
108 void RecalcHash();
110 static bool NameLess(const Item& a, const Item& b);
113 struct SItemsHash
115 std::size_t operator()(const SItems& items) const
117 return items.hash;
121 protected:
122 SItems* m_Items; // interned value
124 private:
125 using InternedItems_t = std::unordered_map<SItems, std::shared_ptr<SItems>, SItemsHash>;
126 static InternedItems_t s_InternedItems;
129 * Returns a pointer to an SItems equal to @p items.
130 * The pointer will be valid forever, and the same pointer will be returned
131 * for any subsequent requests for an equal items list.
133 static SItems* GetInterned(const SItems& items);
135 CShaderParams(SItems* items);
136 static CShaderParams CreateEmpty();
137 static CShaderParams s_Empty;
141 * Represents a mapping of name strings to value strings, for use with
142 * \#if and \#ifdef and similar conditionals in shaders.
144 * Not thread-safe - must only be used from the main thread.
146 class CShaderDefines : public CShaderParams<CStrIntern>
148 public:
150 * Add a name and associated value to the map of defines.
151 * If the name is already defined, its value will be replaced.
153 void Add(CStrIntern name, CStrIntern value);
156 * Return the value for the given name as an integer, or 0 if not defined.
158 int GetInt(const char* name) const;
162 * Represents a mapping of name strings to value CVector4Ds, for use with
163 * uniforms in shaders.
165 * Not thread-safe - must only be used from the main thread.
167 class CShaderUniforms : public CShaderParams<CVector4D>
169 public:
171 * Add a name and associated value to the map of uniforms.
172 * If the name is already defined, its value will be replaced.
174 void Add(const char* name, const CVector4D& value);
177 * Return the value for the given name, or (0,0,0,0) if not defined.
179 CVector4D GetVector(const char* name) const;
182 * Bind the collection of uniforms onto the given shader.
184 void BindUniforms(
185 Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
186 Renderer::Backend::IShaderProgram* shader) const;
189 // Add here the types of queries we can make in the renderer
190 enum RENDER_QUERIES
192 RQUERY_TIME,
193 RQUERY_WATER_TEX,
194 RQUERY_SKY_CUBE
198 * Uniform values that need to be evaluated in the renderer.
200 * Not thread-safe - must only be used from the main thread.
202 class CShaderRenderQueries
204 public:
205 using RenderQuery = std::pair<int, CStrIntern>;
207 void Add(const char* name);
208 size_t GetSize() const { return m_Items.size(); }
209 RenderQuery GetItem(size_t i) const { return m_Items[i]; }
210 private:
211 std::vector<RenderQuery> m_Items;
214 #endif // INCLUDED_SHADERDEFINES