]> git.tdb.fi Git - libs/gl.git/blobdiff - source/programbuilder.h
Visit the rest of an iteration statement in NodeRemover
[libs/gl.git] / source / programbuilder.h
index 69170e02ef979f543b16f1fc53ef0c9adbc0c2d1..053eb567487a9a03964235a5d04b3d84c555a68c 100644 (file)
@@ -18,9 +18,46 @@ public:
        virtual ~invalid_variable_definition() throw() { }
 };
 
+/**
+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 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>
@@ -29,14 +66,52 @@ public:
                        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();
@@ -48,10 +123,14 @@ private:
        enum VariableScope
        {
                NO_SCOPE,
+               TYPE,
+               FUNCTION,
                UNIFORM,
                ATTRIBUTE,
                VERTEX,
-               FRAGMENT
+               GEOMETRY,
+               FRAGMENT,
+               N_SCOPES
        };
 
        enum InterfaceFlags
@@ -59,7 +138,6 @@ private:
                NO_INTERFACE = 0,
                INPUT = 1,
                OUTPUT = 2,
-               PASSTHROUGH = INPUT|OUTPUT,
                GOAL = 4
        };
 
@@ -76,39 +154,51 @@ private:
        {
                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;
                InterfaceFlags get_interface_flags(VariableScope) const;
-               std::string create_declaration(char = 0) const;
-               std::string create_replacement(VariableScope) const;
-               std::string create_expression() 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[];
@@ -117,16 +207,25 @@ private:
 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