virtual ~invalid_variable_definition() throw() { }
};
-class ProgramBuilder
+/**
+Generates shaders with common features.
+
+The shader generation model is based on variable substitutions. Initially, a
+goal variable is given for each shader stage. The expression for computing
+each variable is examined for further variable definitions. When there are no
+more known variables available for substitution, the process terminates. Any
+unknown variables at this point are assumed to be provided by OpenGL.
+
+Variables can be defined in a number of scopes. The scope of a variable
+determines where its value is computed. If a variable is referenced from a
+scope that comes after the declaration scope, an interface variable is
+automatically emitted.
+
+Generated shaders are normally optimized by inlining variables with a single
+reference into the expression referencing them. This can result in expressions
+of several hundreds of characters in length, so optimizations can be disabled
+with the set_optimize() method for debugging purposes.
+
+Custom variables can be injected to the generated shaders with the custom
+member of the StandardFeatures struct. The syntax is:
+
+ <custom> := [<decl> ...]
+ <decl> := <scope> <type> <name> [= <expr>] ;
+ <scope> := uniform | attribute | vertex | fragment
+ <type> := (any GLSL type)
+ <name> := (valid identifier)
+ <expr> := (GLSL expression)
+
+The custom variables should always include at least one override for a built-in
+variable; otherwise they will be ignored as no built-in expression references
+them.
+*/
+class DEPRECATED ProgramBuilder
{
public:
+ /**
+ Describes the features of a standard shader program. All boolean features
+ default to false unless stated otherwise.
+ */
struct StandardFeatures
{
class Loader: public DataFile::ObjectLoader<StandardFeatures>
Loader(StandardFeatures &);
};
+ /** Use a diffuse map texture. */
bool texture;
+
+ /** Use material properties if lighting is true, or vertex colors if
+ lighting is false. */
bool material;
+
+ /** Use lighting to compute the brightness of surfaces. */
bool lighting;
+
+ /** Number of lights to use in lighting calculations. Defaults to 1. */
+ unsigned max_lights;
+
+ /** Use a skylight component for ambient lighting. */
+ bool skylight;
+
+ bool fog;
+
+ /** Use a specular lighting component. */
bool specular;
- bool normalmap;
+
+ /** Use a normal map texture. Only used if lighting is true. */
+ bool normal_map;
+
+ /** Use a shadow map. Requires a ShadowMap effect or equivalent in the
+ pipeline. */
bool shadow;
+
+ /** Use a reflection cube map. Requires an EnvironmentMap effect or
+ equivalend in the pipeline. */
bool reflection;
+
+ /** Clip primitives against user defined clip planes. */
+ bool clipping;
+
+ /** Number of clipping planes to process. */
+ unsigned max_clip_planes;
+
+ /** Use a geometry shader. */
+ bool geometry;
+
+ /** Force the use of legacy shaders conforming to GLSL 1.10. Defaults
+ to true if the version of GLSL is less than 1.30, false otherwise. */
bool legacy;
+
+ /** Custom variables to use in the shader. */
std::string custom;
StandardFeatures();
enum VariableScope
{
NO_SCOPE,
+ TYPE,
+ FUNCTION,
UNIFORM,
ATTRIBUTE,
VERTEX,
- FRAGMENT
+ GEOMETRY,
+ FRAGMENT,
+ N_SCOPES
+ };
+
+ enum InterfaceFlags
+ {
+ NO_INTERFACE = 0,
+ INPUT = 1,
+ OUTPUT = 2,
+ GOAL = 4
};
struct VariableDefinition
{
std::string name;
const VariableDefinition *variable;
+ const VariableDefinition *type;
std::string resolved_name;
+ std::string resolved_block;
bool fuzzy_space;
std::string resolved_space;
+ bool array_sum;
+ std::string array_subscript;
+ unsigned array_size;
std::list<ShaderVariable *> referenced_vars;
std::list<ShaderVariable *> referenced_by;
bool inlined;
bool inline_parens;
+ bool in_loop;
ShaderVariable(const std::string &);
void resolve(const VariableDefinition &);
void resolve(ShaderVariable &);
+ void resolve_type(const VariableDefinition &);
void resolve_space(const std::string &);
+ void resolve_array(const StandardFeatures &, unsigned = 0);
void add_reference(ShaderVariable &);
void update_reference(ShaderVariable &, ShaderVariable &);
void check_inline(bool, bool);
bool is_referenced_from(VariableScope) const;
- std::string get_expression() const;
+ InterfaceFlags get_interface_flags(VariableScope) const;
+ std::string create_type_declaration() const;
+ std::string create_declaration(char = 0, bool = false) const;
+ std::string create_replacement(VariableScope, unsigned, const char * = 0) const;
+ std::string create_expression(unsigned, const char * = 0) const;
};
- enum MatchLevel
+ enum MatchType
{
NO_MATCH,
EXACT,
- FUZZY
+ FUZZY,
+ ARRAY
};
StandardFeatures features;
std::list<VariableDefinition> custom_variables;
std::string feature_flags;
+ unsigned enabled_scopes;
+ std::map<std::string, std::string> aliases;
bool optimize;
static const VariableDefinition standard_variables[];
+ static const char interfaces[];
public:
ProgramBuilder(const StandardFeatures &);
+ /// Enable or disable optimization. Defaults to enabled.
void set_optimize(bool);
+
+ /// Create a new Program with the features associated with the builder.
Program *create_program() const;
+
+ /// Generate shaders and add them to an existing program.
void add_shaders(Program &) const;
+
private:
std::string create_source(const std::list<ShaderVariable *> &, VariableScope) const;
bool evaluate_flags(const char *) const;
- static MatchLevel name_match(const char *, const char *, const char ** = 0);
+ static const char *unqualified_name(const char *);
+ static MatchType name_match(const char *, const char *, const char ** = 0);
static bool parse_identifier(const char *, unsigned &, unsigned &);
static std::vector<std::string> extract_identifiers(const char *);
- static std::string replace_identifiers(const char *, const std::map<std::string, std::string> &);
+ static std::string replace_identifiers(const char *, const std::map<std::string, std::string> &, bool = false);
+ static VariableScope previous_scope(VariableScope, unsigned);
+ std::string create_expression(const ShaderVariable &, const char * = 0) const;
};
} // namespace GL