forked from AcademySoftwareFoundation/MaterialX
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ShaderGenerator.h
227 lines (175 loc) · 9.47 KB
/
ShaderGenerator.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
//
// TM & (c) 2017 Lucasfilm Entertainment Company Ltd. and Lucasfilm Ltd.
// All rights reserved. See LICENSE.txt for license.
//
#ifndef MATERIALX_SHADERGENERATOR_H
#define MATERIALX_SHADERGENERATOR_H
/// @file
/// Base shader generator class
#include <MaterialXGenShader/Library.h>
#include <MaterialXGenShader/ColorManagementSystem.h>
#include <MaterialXGenShader/Factory.h>
#include <MaterialXGenShader/ShaderStage.h>
#include <MaterialXGenShader/Syntax.h>
#include <MaterialXCore/Util.h>
namespace MaterialX
{
/// @class ShaderGenerator
/// Base class for shader generators
/// All third-party shader generators should derive from this class.
/// Derived classes should use DECLARE_SHADER_GENERATOR / DEFINE_SHADER_GENERATOR
/// in their declaration / definition, and register with the Registry class.
class ShaderGenerator
{
public:
/// Destructor
virtual ~ShaderGenerator() { }
/// Return the name of the target this generator is for.
virtual const string& getTarget() const = 0;
/// Generate a shader starting from the given element, translating
/// the element and all dependencies upstream into shader code.
virtual ShaderPtr generate(const string& name, ElementPtr element, GenContext& context) const = 0;
/// Start a new scope using the given bracket type.
virtual void emitScopeBegin(ShaderStage& stage, Syntax::Punctuation punc = Syntax::CURLY_BRACKETS) const;
/// End the current scope.
virtual void emitScopeEnd(ShaderStage& stage, bool semicolon = false, bool newline = true) const;
/// Start a new line.
virtual void emitLineBegin(ShaderStage& stage) const;
/// End the current line.
virtual void emitLineEnd(ShaderStage& stage, bool semicolon = true) const;
/// Add a line break.
virtual void emitLineBreak(ShaderStage& stage) const;
/// Add a string.
virtual void emitString(const string& str, ShaderStage& stage) const;
/// Add a single line of code, optionally appending a semicolon.
virtual void emitLine(const string& str, ShaderStage& stage, bool semicolon = true) const;
/// Add a single line code comment.
virtual void emitComment(const string& str, ShaderStage& stage) const;
/// Add a block of code.
virtual void emitBlock(const string& str, GenContext& context, ShaderStage& stage) const;
/// Add the contents of an include file. Making sure it is
/// only included once for the shader stage.
virtual void emitInclude(const string& file, GenContext& context, ShaderStage& stage) const;
/// Add a value.
template<typename T>
void emitValue(const T& value, ShaderStage& stage) const
{
stage.addValue<T>(value);
}
/// Add the function definition for a single node.
virtual void emitFunctionDefinition(const ShaderNode& node, GenContext& context, ShaderStage& stage) const;
/// Add the function call for a single node.
virtual void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage,
bool checkScope = true) const;
/// Add all function definitions for a graph.
virtual void emitFunctionDefinitions(const ShaderGraph& graph, GenContext& context, ShaderStage& stage) const;
/// Add all function calls for a graph.
virtual void emitFunctionCalls(const ShaderGraph& graph, GenContext& context, ShaderStage& stage) const;
/// Emit type definitions for all data types that needs it.
virtual void emitTypeDefinitions(GenContext& context, ShaderStage& stage) const;
/// Emit the connected variable name for an input,
/// or constant value if the port is not connected
virtual void emitInput(const ShaderInput* input, GenContext& context, ShaderStage& stage) const;
/// Emit the output variable name for an output, optionally including it's type
/// and default value assignment.
virtual void emitOutput(const ShaderOutput* output, bool includeType, bool assignValue, GenContext& context, ShaderStage& stage) const;
/// Emit definitions for all shader variables in a block.
/// @param block Block to emit.
/// @param qualifier Optional qualifier to add before the variable declaration.
/// @param separator Separator to use between the declarations.
/// @param context Context for generation.
/// @param stage The stage to emit code into.
/// @param assignValue If true the variables are initialized with their value.
virtual void emitVariableDeclarations(const VariableBlock& block, const string& qualifier, const string& separator, GenContext& context, ShaderStage& stage,
bool assignValue = true) const;
/// Emit definition of a single shader variable.
/// @param variable Shader port representing the variable.
/// @param qualifier Optional qualifier to add before the variable declaration.
/// @param context Context for generation.
/// @param stage The stage to emit code into.
/// @param assignValue If true the variable is initialized with its value.
virtual void emitVariableDeclaration(const ShaderPort* variable, const string& qualifier, GenContext& context, ShaderStage& stage,
bool assignValue = true) const;
/// Return the result of an upstream connection or value for an input.
virtual string getUpstreamResult(const ShaderInput* input, GenContext& context) const;
/// Return the syntax object for the language used by the code generator
const Syntax& getSyntax() const { return *_syntax; }
/// Register a shader node implementation for a given implementation element name
void registerImplementation(const string& name, CreatorFunction<ShaderNodeImpl> creator);
/// Determine if a shader node implementation has been registered for a given implementation element name
bool implementationRegistered(const string& name) const;
/// Sets the color management system
void setColorManagementSystem(ColorManagementSystemPtr colorManagementSystem)
{
_colorManagementSystem = colorManagementSystem;
}
/// Returns the color management system
ColorManagementSystemPtr getColorManagementSystem() const
{
return _colorManagementSystem;
}
/// Sets the unit system
void setUnitSystem(UnitSystemPtr unitSystem)
{
_unitSystem = unitSystem;
}
/// Returns the unit system
UnitSystemPtr getUnitSystem() const
{
return _unitSystem;
}
/// Return a registered shader node implementation given an implementation element.
/// The element must be an Implementation or a NodeGraph acting as implementation.
/// If no registered implementation is found a 'default' implementation instance
/// will be returned, as defined by the createDefaultImplementation method.
ShaderNodeImplPtr getImplementation(const InterfaceElement& element, GenContext& context) const;
/// Return the map of token substitutions used by the generator.
const StringMap& getTokenSubstitutions() const
{
return _tokenSubstitutions;
}
/// Register metadata that should be exported to the generated shaders.
/// Supported metadata includes standard UI attributes like "uiname", "uifolder",
/// "uimin", "uimax", etc.
/// But it is also extendable by defining custom attributes using AttributeDefs.
/// Any AttributeDef in the given document with exportable="true" will be
/// exported as shader metadata when found on nodes during shader generation.
/// Derived shader generators may override this method to change the registration.
/// Applications must explicitly call this method before shader generation to enable
/// export of metadata.
virtual void registerShaderMetadata(const DocumentPtr& doc, GenContext& context) const;
protected:
/// Protected constructor
ShaderGenerator(SyntaxPtr syntax);
/// Create a new stage in a shader.
virtual ShaderStagePtr createStage(const string& name, Shader& shader) const;
/// Create a source code implementation which is the implementation class to use
/// for nodes that has no specific C++ implementation registered for it.
/// Derived classes can override this to use custom source code implementations.
virtual ShaderNodeImplPtr createSourceCodeImplementation(const Implementation& impl) const;
/// Create a compound implementation which is the implementation class to use
/// for nodes using a nodegraph as their implementation.
/// Derived classes can override this to use custom compound implementations.
virtual ShaderNodeImplPtr createCompoundImplementation(const NodeGraph& impl) const;
/// Method called on all created shader graphs. By default it does nothing,
/// but shader generators can override this to perform custom edits on the graph
/// before shader generation starts.
virtual void finalizeShaderGraph(ShaderGraph& graph);
/// Set function name for a stage.
void setFunctionName(const string& functionName, ShaderStage& stage) const
{
stage.setFunctionName(functionName);
}
/// Replace tokens with identifiers according to the given substitutions map.
void replaceTokens(const StringMap& substitutions, ShaderStage& stage) const;
protected:
static const string T_FILE_TRANSFORM_UV;
SyntaxPtr _syntax;
Factory<ShaderNodeImpl> _implFactory;
ColorManagementSystemPtr _colorManagementSystem;
UnitSystemPtr _unitSystem;
mutable StringMap _tokenSubstitutions;
friend ShaderGraph;
};
} // namespace MaterialX
#endif // MATERIALX_SHADERGENERATOR_H