/
ishaders.h
437 lines (365 loc) · 13.2 KB
/
ishaders.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
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
#pragma once
#include "iimage.h"
#include "imodule.h"
#include "ifilesystem.h"
#include <sigc++/signal.h>
#include "math/Vector3.h"
#include "math/Vector4.h"
#include <ostream>
#include <vector>
#include "Texture.h"
#include "ShaderLayer.h"
#include "ishaderexpression.h"
class Image;
// Forward declaration
namespace shaders {
class MapExpression;
typedef std::shared_ptr<MapExpression> MapExpressionPtr;
} // namespace shaders
/**
* \brief Interface for a material shader.
*
* A material shader consists of global parameters, an editor image, and zero
* or more shader layers (including diffusemap, bumpmap and specularmap
* textures which are handled specially).
*
* Most material shaders are defined in .mtr files within the mod asset tree,
* but there are also internal materials generated for Radiant-specific
* internal OpenGL shaders, such as those used to render wireframes.
*/
class Material
{
public:
enum CullType
{
CULL_BACK, // default backside culling, for materials without special flags
CULL_FRONT, // "backSided"
CULL_NONE, // "twoSided"
};
// Global material flags
enum Flags
{
FLAG_NOSHADOWS = 1 << 0, // noShadows
FLAG_NOSELFSHADOW = 1 << 1, // noSelfShadow
FLAG_FORCESHADOWS = 1 << 2, // forceShadows
FLAG_NOOVERLAYS = 1 << 3, // noOverlays
FLAG_FORCEOVERLAYS = 1 << 4, // forceOverlays
FLAG_TRANSLUCENT = 1 << 5, // translucent
FLAG_FORCEOPAQUE = 1 << 6, // forceOpaque
FLAG_NOFOG = 1 << 7, // noFog
FLAG_NOPORTALFOG = 1 << 8, // noPortalFog
FLAG_UNSMOOTHEDTANGENTS = 1 << 9, // unsmoothedTangents
FLAG_MIRROR = 1 << 10, // mirror
};
// Surface Flags
enum SurfaceFlags
{
SURF_SOLID = 1 << 0,
SURF_OPAQUE = 1 << 1,
SURF_WATER = 1 << 2,
SURF_PLAYERCLIP = 1 << 3,
SURF_MONSTERCLIP = 1 << 4,
SURF_MOVEABLECLIP = 1 << 5,
SURF_IKCLIP = 1 << 6,
SURF_BLOOD = 1 << 7,
SURF_TRIGGER = 1 << 8,
SURF_AASSOLID = 1 << 9,
SURF_AASOBSTACLE = 1 << 10,
SURF_FLASHLIGHT_TRIGGER = 1 << 11,
SURF_NONSOLID = 1 << 12,
SURF_NULLNORMAL = 1 << 13,
SURF_AREAPORTAL = 1 << 14,
SURF_NOCARVE = 1 << 15,
SURF_DISCRETE = 1 << 16,
SURF_NOFRAGMENT = 1 << 17,
SURF_SLICK = 1 << 18,
SURF_COLLISION = 1 << 19,
SURF_NOIMPACT = 1 << 20,
SURF_NODAMAGE = 1 << 21,
SURF_LADDER = 1 << 22,
SURF_NOSTEPS = 1 << 23,
SURF_ENTITYGUI = 1 << 24,
};
// Surface Type (plastic, stone, etc.)
enum SurfaceType
{
SURFTYPE_DEFAULT,
SURFTYPE_METAL,
SURFTYPE_STONE,
SURFTYPE_FLESH,
SURFTYPE_WOOD,
SURFTYPE_CARDBOARD,
SURFTYPE_LIQUID,
SURFTYPE_GLASS,
SURFTYPE_PLASTIC,
SURFTYPE_RICOCHET,
SURFTYPE_AASOBSTACLE,
SURFTYPE_10,
SURFTYPE_11,
SURFTYPE_12,
SURFTYPE_13,
SURFTYPE_14,
SURFTYPE_15
};
/**
* \brief
* Requested sort position from material declaration (e.g. "sort decal").
* The actual sort order of a material is stored as a floating point number,
* these enumerations represent some regularly used shortcuts in material decls.
* The values of this enum have been modeled after the ones found in the D3 SDK.
*/
enum SortRequest
{
SORT_SUBVIEW = -3, // mirrors, viewscreens, etc
SORT_GUI = -2, // guis
SORT_BAD = -1,
SORT_OPAQUE, // opaque
SORT_PORTAL_SKY,
SORT_DECAL, // scorch marks, etc.
SORT_FAR,
SORT_MEDIUM, // normal translucent
SORT_CLOSE,
SORT_ALMOST_NEAREST, // gun smoke puffs
SORT_NEAREST, // screen blood blobs
SORT_POST_PROCESS = 100 // after a screen copy to texture
};
// Deform Type
enum DeformType
{
DEFORM_NONE,
DEFORM_SPRITE,
DEFORM_TUBE,
DEFORM_FLARE,
DEFORM_EXPAND,
DEFORM_MOVE,
DEFORM_TURBULENT,
DEFORM_EYEBALL,
DEFORM_PARTICLE,
DEFORM_PARTICLE2,
};
struct DecalInfo
{
int stayMilliSeconds;
int fadeMilliSeconds;
Vector4 startColour;
Vector4 endColour;
};
enum Coverage
{
MC_UNDETERMINED,
MC_OPAQUE, // completely fills the triangle, will have black drawn on fillDepthBuffer
MC_PERFORATED, // may have alpha tested holes
MC_TRANSLUCENT // blended with background
};
virtual ~Material() {}
/// Return the editor image texture for this shader.
virtual TexturePtr getEditorImage() { return {}; }
/// Return true if the editor image is no tex for this shader.
virtual bool isEditorImageNoTex() { return false; }
/// Get the string name of this material
virtual std::string getName() const = 0;
virtual bool IsInUse() const { return true; }
virtual void SetInUse(bool bInUse) {}
/// Return true if this is an internal material not corresponding to a .mtr
virtual bool IsDefault() const { return false; }
/// get shader file name (ie the file where this one is defined)
virtual const char* getShaderFileName() const { return ""; }
// Returns the VFS info structure of the file this shader is defined in
virtual const vfs::FileInfo* getShaderFileInfo() const { return nullptr; }
/**
* \brief Return the requested sort position of this material.
*
* greebo: D3 is using floating points for the sort value but
* as far as I can see only rounded numbers have been used.
*/
virtual int getSortRequest() const { return 0; }
/// Return a polygon offset if one is defined. The default is 0.
virtual float getPolygonOffset() const { return 0; }
/// Get the desired texture repeat behaviour.
virtual ClampType getClampType() const { return CLAMP_REPEAT; }
/// Get the cull type (none, back, front)
virtual CullType getCullType() const { return CULL_BACK; }
/// Get the global material flags (translucent, noshadows, etc.)
virtual int getMaterialFlags() const { return 0; }
/// Surface flags (areaportal, nonsolid, etc.)
virtual int getSurfaceFlags() const { return 0; }
/// Surface Type (wood, stone, surfType15, ...)
virtual SurfaceType getSurfaceType() const { return SURFTYPE_DEFAULT; }
/// Get the deform type of this material
virtual DeformType getDeformType() const { return DEFORM_NONE; }
/// Returns the spectrum of this shader, -1 means "no defined spectrum"
virtual int getSpectrum() const { return -1; }
/// Retrieves the decal info structure of this material.
virtual DecalInfo getDecalInfo() const { return {}; }
/// Returns the coverage type of this material, also needed by the map compiler.
virtual Coverage getCoverage() const { return MC_OPAQUE; }
/**
* Returns the raw shader definition block, as parsed by the material manager.
* The definition is lacking the outermost curly braces.
*/
virtual std::string getDefinition() { return {}; }
/** Determine whether this is an ambient light shader, i.e. the
* material def contains the global "ambientLight" keyword.
*/
virtual bool isAmbientLight() const { return false; }
/** Determine whether this is an blend light shader, i.e. the
* material def contains the global "blendLight" keyword.
*/
virtual bool isBlendLight() const { return false; }
/** Determine whether this is an fog light shader, i.e. the
* material def contains the global "fogLight" keyword.
*/
virtual bool isFogLight() const { return false; }
/**
* For light shaders: implicitly no-shadows lights (ambients, fogs, etc)
* will never cast shadows but individual light entities can also override this value.
*/
virtual bool lightCastsShadows() const { return true; }
// returns true if the material will generate shadows, not making a
// distinction between global and no-self shadows
virtual bool surfaceCastsShadow() const { return true; }
/**
* returns true if the material will draw anything at all. Triggers, portals,
* etc, will not have anything to draw. A not drawn surface can still castShadow,
* which can be used to make a simplified shadow hull for a complex object set as noShadow.
*/
virtual bool isDrawn() const { return true; }
/**
* a discrete surface will never be merged with other surfaces by dmap, which is
* necessary to prevent mutliple gui surfaces, mirrors, autosprites, and some other
* special effects from being combined into a single surface
* guis, merging sprites or other effects, mirrors and remote views are always discrete
*/
virtual bool isDiscrete() const { return false; }
/// Return the first material layer, if any
virtual ShaderLayer* firstLayer() const { return nullptr; }
/**
* \brief Return a std::vector containing all layers in this material
* shader.
*
* This includes all diffuse, bump, specular or blend layers.
*/
virtual ShaderLayerVector getAllLayers() const { return {}; }
/// Return the 2D light falloff texture, if this is a light shader
virtual TexturePtr lightFalloffImage() { return {}; }
// greebo: Returns the description as defined in the material
virtual std::string getDescription() const { return {}; }
/// Return TRUE if the shader is visible, FALSE if it is filtered or
/// disabled in any other way.
virtual bool isVisible() const { return true; }
/// Sets the visibility of this shader.
virtual void setVisible(bool visible) {}
};
typedef std::shared_ptr<Material> MaterialPtr;
/// Stream insertion of Material for debugging purposes.
inline
std::ostream& operator<< (std::ostream& os, const Material& shader)
{
os << "Material(name=" << shader.getName()
<< ", filename=" << shader.getShaderFileName()
<< ", firstlayer=" << shader.firstLayer()
<< ")";
return os;
}
/// Debug stream insertion of possibly null material pointer
inline std::ostream& operator<< (std::ostream& os, const Material* m)
{
if (m)
return os << *m;
else
return os << "[no material]";
}
typedef std::function<void(const std::string&)> ShaderNameCallback;
const char* const MODULE_SHADERSYSTEM = "MaterialManager";
/**
* \brief
* Interface for the material manager.
*
* The material manager parses all of the MTR declarations and provides access
* to Material objects representing the loaded materials.
*/
class MaterialManager
: public RegisterableModule
{
public:
// NOTE: shader and texture names used must be full path.
// Shaders usable as textures have prefix equal to getTexturePrefix()
virtual void realise() = 0;
virtual void unrealise() = 0;
virtual void refresh() = 0;
/** Determine whether the shader system is realised. This may be used
* by components which need to ensure the shaders are realised before
* they start trying to display them.
*
* @returns
* true if the shader system is realised, false otherwise
*/
virtual bool isRealised() = 0;
// Signal which is invoked when the materials defs have been parsed
// Note that the DEF files might be parsed in a separate thread so
// any call acquiring material info might need to block and wait for
// that background call to finish before it can yield results.
virtual sigc::signal<void>& signal_DefsLoaded() = 0;
// Signal invoked when the material defs have been unloaded due
// to a filesystem or other configuration change
virtual sigc::signal<void>& signal_DefsUnloaded() = 0;
/** Activate the shader for a given name and return it. The default shader
* will be returned if name is not found.
*
* @param name
* The text name of the shader to load.
*
* @returns
* MaterialPtr shared ptr corresponding to the named shader object.
*/
virtual MaterialPtr getMaterialForName(const std::string& name) = 0;
/**
* greebo: Returns true if the named material is existing, false otherwise.
* In the latter case getMaterialForName() would return a default "shader not found".
*/
virtual bool materialExists(const std::string& name) = 0;
virtual void foreachShaderName(const ShaderNameCallback& callback) = 0;
/**
* Visit each material with the given function object. Replaces the legacy foreachShader().
*/
virtual void foreachMaterial(const std::function<void(const MaterialPtr&)>& func) = 0;
// Set the callback to be invoked when the active shaders list has changed
virtual sigc::signal<void> signal_activeShadersChanged() const = 0;
/**
* Enable or disable active shaders updates (for performance).
*/
virtual void setActiveShaderUpdates(bool val) = 0;
virtual void setLightingEnabled(bool enabled) = 0;
virtual const char* getTexturePrefix() const = 0;
/**
* \brief
* Return the default texture to be used for lighting mode rendering if it
* is not defined for a shader.
*
* \param type
* The type of interaction layer whose default texture is required.
*/
virtual TexturePtr getDefaultInteractionTexture(ShaderLayer::Type type) = 0;
/**
* greebo: This is a substitution for the "old" TexturesCache method
* used to load an image from a file to graphics memory for arbitrary
* use (e.g. the Overlay module).
*
* @param filename
* The absolute filename.
*
* @param moduleNames
* The space-separated list of image modules (default is "GDK").
*/
virtual TexturePtr loadTextureFromFile(const std::string& filename) = 0;
/**
* Creates a new shader expression for the given string. This can be used to create standalone
* expression objects for unit testing purposes.
*/
virtual shaders::IShaderExpressionPtr createShaderExpressionFromString(const std::string& exprStr) = 0;
};
inline MaterialManager& GlobalMaterialManager()
{
static module::InstanceReference<MaterialManager> _reference(MODULE_SHADERSYSTEM);
return _reference;
}