/
ShaderTemplate.h
373 lines (294 loc) · 8.28 KB
/
ShaderTemplate.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
#pragma once
#include "MapExpression.h"
#include "Doom3ShaderLayer.h"
#include "ishaders.h"
#include "parser/DefTokeniser.h"
#include "math/Vector3.h"
#include <map>
#include <memory>
namespace shaders { class MapExpression; }
namespace shaders
{
/**
* Data structure storing parsed material information from a material decl. This
* class parses the decl using a tokeniser and stores the relevant information
* internally, for later use by a CShader.
*/
class ShaderTemplate final
{
private:
static const int SORT_UNDEFINED = -99999; // undefined sort number, will be replaced after parsing
// Template name
std::string _name;
// Temporary current layer (used by the parsing functions)
Doom3ShaderLayerPtr _currentLayer;
public:
// Vector of LayerTemplates representing each stage in the material
std::vector<Doom3ShaderLayerPtr> _layers;
// Editorimage texture
NamedBindablePtr _editorTex;
// Map expressions
MapExpressionPtr _lightFalloff;
MapExpressionPtr _lightFalloffCubeMap;
/* Light type booleans */
bool fogLight;
bool ambientLight;
bool blendLight;
bool _cubicLight;
// The description tag of the material
std::string description;
// Material flags
int _materialFlags;
// cull type
Material::CullType _cullType;
// texure repeat type
ClampType _clampType;
// Surface flags (nonsolid, areaportal, etc.)
int _surfaceFlags;
Material::SurfaceType _surfaceType;
Material::DeformType _deformType;
std::vector<IShaderExpressionPtr> _deformExpressions;
std::string _deformDeclName;
// The spectrum this shader is responding to (or emitting in the case of light materials)
int _spectrum;
// Sort position (e.g. sort decal == 2)
int _sortReq;
// Polygon offset
float _polygonOffset;
Material::DecalInfo _decalInfo;
// Whether this material renders opaque, perforated, etc.
Material::Coverage _coverage;
std::string _renderBumpArguments;
std::string _renderBumpFlatArguments;
// Raw material declaration
std::string _blockContents;
// Whether the block has been parsed
bool _parsed;
int _parseFlags;
// The string value specified by the guisurf keyword, if other than entity[2]3]
std::string _guiDeclName;
// Private copy ctor, used for cloning
ShaderTemplate(const ShaderTemplate& other);
public:
/**
* \brief
* Construct a ShaderTemplate.
*/
ShaderTemplate(const std::string& name, const std::string& blockContents)
: _name(name),
_currentLayer(new Doom3ShaderLayer(*this)),
fogLight(false),
ambientLight(false),
blendLight(false),
_cubicLight(false),
_materialFlags(0),
_cullType(Material::CULL_BACK),
_clampType(CLAMP_REPEAT),
_surfaceFlags(0),
_surfaceType(Material::SURFTYPE_DEFAULT),
_deformType(Material::DEFORM_NONE),
_spectrum(0),
_sortReq(SORT_UNDEFINED), // will be set to default values after the shader has been parsed
_polygonOffset(0.0f),
_coverage(Material::MC_UNDETERMINED),
_blockContents(blockContents),
_parsed(false),
_parseFlags(0)
{
_decalInfo.stayMilliSeconds = 0;
_decalInfo.fadeMilliSeconds = 0;
_decalInfo.startColour = Vector4(1,1,1,1);
_decalInfo.endColour = Vector4(0,0,0,0);
}
// Clone a new instance from this template
std::shared_ptr<ShaderTemplate> clone() const;
/**
* Get the name of this shader template.
*/
const std::string& getName() const
{
return _name;
}
/**
* Set the name of this shader template.
*/
void setName(const std::string& name)
{
_name = name;
}
const std::string& getDescription()
{
if (!_parsed) parseDefinition();
return description;
}
int getMaterialFlags()
{
if (!_parsed) parseDefinition();
return _materialFlags;
}
void setMaterialFlag(Material::Flags flag)
{
if (!_parsed) parseDefinition();
_materialFlags |= flag;
}
void clearMaterialFlag(Material::Flags flag)
{
if (!_parsed) parseDefinition();
_materialFlags &= ~flag;
}
Material::CullType getCullType()
{
if (!_parsed) parseDefinition();
return _cullType;
}
ClampType getClampType()
{
if (!_parsed) parseDefinition();
return _clampType;
}
int getSurfaceFlags()
{
if (!_parsed) parseDefinition();
return _surfaceFlags;
}
Material::SurfaceType getSurfaceType()
{
if (!_parsed) parseDefinition();
return _surfaceType;
}
Material::DeformType getDeformType()
{
if (!_parsed) parseDefinition();
return _deformType;
}
IShaderExpressionPtr getDeformExpression(std::size_t index)
{
if (!_parsed) parseDefinition();
assert(index >= 0 && index < 3);
return index < _deformExpressions.size() ? _deformExpressions[index] : IShaderExpressionPtr();
}
std::string getDeformDeclName()
{
if (!_parsed) parseDefinition();
return _deformDeclName;
}
int getSpectrum()
{
if (!_parsed) parseDefinition();
return _spectrum;
}
const Material::DecalInfo& getDecalInfo()
{
if (!_parsed) parseDefinition();
return _decalInfo;
}
Material::Coverage getCoverage()
{
if (!_parsed) parseDefinition();
return _coverage;
}
const std::vector<Doom3ShaderLayerPtr>& getLayers()
{
if (!_parsed) parseDefinition();
return _layers;
}
bool isFogLight()
{
if (!_parsed) parseDefinition();
return fogLight;
}
bool isAmbientLight()
{
if (!_parsed) parseDefinition();
return ambientLight;
}
bool isBlendLight()
{
if (!_parsed) parseDefinition();
return blendLight;
}
bool isCubicLight()
{
if (!_parsed) parseDefinition();
return _cubicLight;
}
int getSortRequest()
{
if (!_parsed) parseDefinition();
return _sortReq;
}
float getPolygonOffset()
{
if (!_parsed) parseDefinition();
return _polygonOffset;
}
// Sets the raw block definition contents, will be parsed on demand
void setBlockContents(const std::string& blockContents)
{
_blockContents = blockContents;
}
const std::string& getBlockContents() const
{
return _blockContents;
}
/**
* \brief
* Return the named bindable corresponding to the editor preview texture
* (qer_editorimage).
*/
NamedBindablePtr getEditorTexture();
const MapExpressionPtr& getLightFalloff()
{
if (!_parsed) parseDefinition();
return _lightFalloff;
}
const MapExpressionPtr& getLightFalloffCubeMap()
{
if (!_parsed) parseDefinition();
return _lightFalloffCubeMap;
}
// Add a specific layer to this template
void addLayer(ShaderLayer::Type type, const MapExpressionPtr& mapExpr);
// Returns true if this shader template includes a diffusemap stage
bool hasDiffusemap();
// Parser hints
int getParseFlags();
// renderbump argument string
std::string getRenderBumpArguments();
// renderbumpflat argument string
std::string getRenderBumpFlagArguments();
const std::string& getGuiSurfArgument()
{
if (!_parsed) parseDefinition();
return _guiDeclName;
}
private:
// Add the given layer and assigns editor preview layer if applicable
void addLayer(const Doom3ShaderLayerPtr& layer);
/**
* Parse a Doom 3 material decl. This is the master parse function, it
* returns no value but exceptions may be thrown at any stage of the
* parsing.
*/
void parseDefinition();
// Parse helpers. These scan for possible matches, this is not a
// recursive-descent parser. Each of these helpers return true
// if the token was recognised and parsed
bool parseShaderFlags(parser::DefTokeniser&, const std::string&);
bool parseLightKeywords(parser::DefTokeniser&, const std::string&);
bool parseBlendShortcuts(parser::DefTokeniser&, const std::string&);
bool parseBlendType(parser::DefTokeniser&, const std::string&);
bool parseBlendMaps(parser::DefTokeniser&, const std::string&);
bool parseStageModifiers(parser::DefTokeniser&, const std::string&);
bool parseSurfaceFlags(parser::DefTokeniser&, const std::string&);
bool parseMaterialType(parser::DefTokeniser&, const std::string&);
bool parseCondition(parser::DefTokeniser&, const std::string&);
IShaderExpressionPtr parseSingleExpressionTerm(parser::DefTokeniser& tokeniser);
bool saveLayer();
};
/* TYPEDEFS */
// Pointer to ShaderTemplate
typedef std::shared_ptr<ShaderTemplate> ShaderTemplatePtr;
// Map of named ShaderTemplates
typedef std::map<std::string, ShaderTemplatePtr> ShaderTemplateMap;
}