forked from autodesk-forks/MaterialX
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathShaderGenerator.h
223 lines (172 loc) · 9.26 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
//
// 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 a unique identifier for the language used by this generator
virtual const string& getLanguage() const = 0;
/// Return a unique identifier for 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;
/// Given an input specification attempt to remap this to an enumeration which is accepted by
/// the shader generator. The enumeration may be converted to a different type than the input.
/// @param input Nodedef input potentially holding an enum definition.
/// @param value The value string to remap.
/// @param result Enumeration type and value (returned).
/// @return Return true if the remapping was successful.
virtual bool remapEnumeration(const ValueElement& input, const string& value,
std::pair<const TypeDesc*, ValuePtr>& result) const;
/// Return the map of token substitutions used by the generator.
const StringMap& getTokenSubstitutions() const
{
return _tokenSubstitutions;
}
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;
/// 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 SEMICOLON;
static const string COMMA;
static const string T_FILE_TRANSFORM_UV;
SyntaxPtr _syntax;
Factory<ShaderNodeImpl> _implFactory;
ColorManagementSystemPtr _colorManagementSystem;
UnitSystemPtr _unitSystem;
mutable StringMap _tokenSubstitutions;
};
} // namespace MaterialX
#endif // MATERIALX_SHADERGENERATOR_H