1 #ifndef MSP_GL_PROGRAMBUILDER_H_
2 #define MSP_GL_PROGRAMBUILDER_H_
7 #include <msp/datafile/objectloader.h>
14 class invalid_variable_definition: public std::invalid_argument
17 invalid_variable_definition(const std::string &w): std::invalid_argument(w) { }
18 virtual ~invalid_variable_definition() throw() { }
22 Generates shaders with common features.
24 The shader generation model is based on variable substitutions. Initially, a
25 goal variable is given for each shader stage. The expression for computing
26 each variable is examined for further variable definitions. When there are no
27 more known variables available for substitution, the process terminates. Any
28 unknown variables at this point are assumed to be provided by OpenGL.
30 Variables can be defined in a number of scopes. The scope of a variable
31 determines where its value is computed. If a variable is referenced from a
32 scope that comes after the declaration scope, an interface variable is
33 automatically emitted.
35 Generated shaders are normally optimized by inlining variables with a single
36 reference into the expression referencing them. This can result in expressions
37 of several hundreds of characters in length, so optimizations can be disabled
38 with the set_optimize() method for debugging purposes.
40 Custom variables can be injected to the generated shaders with the custom
41 member of the StandardFeatures struct. The syntax is:
43 <custom> := [<decl> ...]
44 <decl> := <scope> <type> <name> [= <expr>] ;
45 <scope> := uniform | attribute | vertex | fragment
46 <type> := (any GLSL type)
47 <name> := (valid identifier)
48 <expr> := (GLSL expression)
50 The custom variables should always include at least one override for a built-in
51 variable; otherwise they will be ignored as no built-in expression references
58 Describes the features of a standard shader program. All boolean features
59 default to false unless stated otherwise.
61 struct StandardFeatures
63 class Loader: public DataFile::ObjectLoader<StandardFeatures>
66 Loader(StandardFeatures &);
69 /** Use a diffuse map texture. */
72 /** Use material properties if lighting is true, or vertex colors if
76 /** Use lighting to compute the brightness of surfaces. */
79 /** Number of lights to use in lighting calculations. Defaults to 1. */
82 /** Use a skylight component for ambient lighting. */
87 /** Use a specular lighting component. */
90 /** Use a normal map texture. Only used if lighting is true. */
93 /** Use a shadow map. Requires a ShadowMap effect or equivalent in the
97 /** Use a reflection cube map. Requires an EnvironmentMap effect or
98 equivalend in the pipeline. */
101 /** Clip primitives against user defined clip planes. */
104 /** Number of clipping planes to process. */
105 unsigned max_clip_planes;
107 /** Use a geometry shader. */
110 /** Force the use of legacy shaders conforming to GLSL 1.10. Defaults
111 to true if the version of GLSL is less than 1.30, false otherwise. */
114 /** Custom variables to use in the shader. */
119 std::string create_flags() const;
144 struct VariableDefinition
149 const char *expression;
153 struct ShaderVariable
156 const VariableDefinition *variable;
157 const VariableDefinition *type;
158 std::string resolved_name;
159 std::string resolved_block;
161 std::string resolved_space;
163 std::string array_subscript;
165 std::list<ShaderVariable *> referenced_vars;
166 std::list<ShaderVariable *> referenced_by;
171 ShaderVariable(const std::string &);
173 void resolve(const VariableDefinition &);
174 void resolve(ShaderVariable &);
175 void resolve_type(const VariableDefinition &);
176 void resolve_space(const std::string &);
177 void resolve_array(const StandardFeatures &, unsigned = 0);
178 void add_reference(ShaderVariable &);
179 void update_reference(ShaderVariable &, ShaderVariable &);
180 void check_inline(bool, bool);
181 bool is_referenced_from(VariableScope) const;
182 InterfaceFlags get_interface_flags(VariableScope) const;
183 std::string create_type_declaration() const;
184 std::string create_declaration(char = 0, bool = false) const;
185 std::string create_replacement(VariableScope, unsigned, const char * = 0) const;
186 std::string create_expression(unsigned, const char * = 0) const;
197 StandardFeatures features;
198 std::list<VariableDefinition> custom_variables;
199 std::string feature_flags;
200 unsigned enabled_scopes;
201 std::map<std::string, std::string> aliases;
204 static const VariableDefinition standard_variables[];
205 static const char interfaces[];
208 ProgramBuilder(const StandardFeatures &);
210 /// Enable or disable optimization. Defaults to enabled.
211 void set_optimize(bool);
213 /// Create a new Program with the features associated with the builder.
214 Program *create_program() const;
216 /// Generate shaders and add them to an existing program.
217 void add_shaders(Program &) const;
220 std::string create_source(const std::list<ShaderVariable *> &, VariableScope) const;
221 bool evaluate_flags(const char *) const;
222 static const char *unqualified_name(const char *);
223 static MatchType name_match(const char *, const char *, const char ** = 0);
224 static bool parse_identifier(const char *, unsigned &, unsigned &);
225 static std::vector<std::string> extract_identifiers(const char *);
226 static std::string replace_identifiers(const char *, const std::map<std::string, std::string> &, bool = false);
227 static VariableScope previous_scope(VariableScope, unsigned);
228 std::string create_expression(const ShaderVariable &, const char * = 0) const;